13 use atlas_module,
only: atlas_field, atlas_fieldset
17 use fckit_configuration_module,
only: fckit_configuration
18 use fckit_log_module,
only : log
22 use type_bump,
only: bump_type
40 type(fckit_mpi_comm) :: f_comm
44 logical :: thispe = .false.
45 integer :: nx, ny, nxg, nyg
49 character(len=1024) :: filename
50 integer,
allocatable :: istart2(:), icount2(:)
51 integer,
allocatable :: istart3(:), icount3(:)
52 integer,
allocatable :: istarte(:), icounte(:)
72 call log%debug(
"fv3jedi_io_latlon_mod%setup_conf starting")
76 call log%debug(
"fv3jedi_io_latlon_mod%setup_conf done")
88 type(datetime),
intent(in) :: vdate
91 character(len=4) :: yyyy
92 character(len=2) :: mm, dd, hh, min, ss
94 call log%debug(
"fv3jedi_io_latlon_mod%setup_date starting")
96 call log%debug(
"fv3jedi_io_latlon_mod%setup_date done")
107 call log%debug(
"fv3jedi_io_latlon_mod%delete starting")
111 call log%debug(
"fv3jedi_io_latlon_mod%delete done")
117 subroutine write(self, geom, fields, f_conf, vdate)
123 type(fckit_configuration),
intent(in) :: f_conf
124 type(datetime),
intent(in) :: vdate
128 call log%debug(
"fv3jedi_io_latlon_mod%write starting")
134 call log%debug(
"fv3jedi_io_latlon_mod%write done")
151 integer :: i, j, ji, jj, ii, locs_nlocs, ierr
152 real(kind=
kind_real),
allocatable :: locs_lat(:), locs_lon(:)
157 llgeom%f_comm = geom%f_comm
160 if (llgeom%f_comm%size() >= 12)
then
161 llgeom%layout(1) = 12
163 elseif (llgeom%f_comm%size() >= 6)
then
167 call abor1_ftn(
"create_latlon error: fewer than 6 npes not anticipated")
169 llgeom%npes = llgeom%layout(1) * llgeom%layout(2)
176 llgeom%nxg = 4*(geom%npx - 1)
177 llgeom%nyg = 2*(geom%npy - 1) + 1
181 color = mpi_undefined
183 if (llgeom%f_comm%rank() <= llgeom%npes-1)
then
186 color = int(llgeom%f_comm%communicator() / 2)
188 llgeom%thispe = .true.
191 dx = 360.0_kind_real / (real(llgeom%nxg,
kind_real) - 1.0_kind_real)
192 dy = 180.0_kind_real / (real(llgeom%nyg,
kind_real) - 1.0_kind_real)
194 llgeom%nx = llgeom%nxg / llgeom%layout(1)
195 llgeom%ny = llgeom%nyg / llgeom%layout(2)
197 allocate(llgeom%lons(llgeom%nx))
198 allocate(llgeom%lats(llgeom%ny))
201 llgeom%lons(1) = dx * llgeom%nx * llgeom%f_comm%rank()
203 llgeom%lons(i) = llgeom%lons(i-1) + dx
207 llgeom%lats(1) = -90.0_kind_real
209 llgeom%lats(i) = llgeom%lats(i-1) + dy
212 locs_nlocs = llgeom%nx*llgeom%ny
213 allocate(locs_lon(locs_nlocs))
214 allocate(locs_lat(locs_nlocs))
220 locs_lon(ii) = llgeom%lons(ji)
221 locs_lat(ii) = llgeom%lats(jj)
228 allocate(locs_lon(0))
229 allocate(locs_lat(0))
233 call llgeom%bump%setup(geom%f_comm, geom%isc, geom%iec, geom%jsc, geom%jec, geom%npz, &
234 geom%grid_lon(geom%isc:geom%iec, geom%jsc:geom%jec), &
235 geom%grid_lat(geom%isc:geom%iec, geom%jsc:geom%jec), &
236 locs_nlocs, locs_lon, locs_lat)
245 allocate(llgeom%istart3(4),llgeom%icount3(4))
246 allocate(llgeom%istarte(4),llgeom%icounte(4))
247 allocate(llgeom%istart2(3),llgeom%icount2(3))
248 llgeom%istart3(1) = llgeom%nx * llgeom%f_comm%rank() + 1; llgeom%icount3(1) = llgeom%nx
249 llgeom%istart3(2) = 1; llgeom%icount3(2) = llgeom%ny
250 llgeom%istart3(3) = 1; llgeom%icount3(3) = geom%npz
251 llgeom%istart3(4) = 1; llgeom%icount3(4) = 1
252 llgeom%istart2(1) = llgeom%istart3(1); llgeom%icount2(1) = llgeom%icount3(1)
253 llgeom%istart2(2) = llgeom%istart3(2); llgeom%icount2(2) = llgeom%icount3(2)
254 llgeom%istart2(3) = llgeom%istart3(4); llgeom%icount2(3) = llgeom%icount3(4)
256 llgeom%istarte = llgeom%istarte
257 llgeom%icounte = llgeom%icount3
258 llgeom%istarte(3) = geom%npz + 1
271 if (llgeom%thispe)
then
272 deallocate(llgeom%lons)
273 deallocate(llgeom%lats)
275 deallocate ( llgeom%istart2, llgeom%icount2 )
276 deallocate ( llgeom%istart3, llgeom%icount3 )
277 deallocate ( llgeom%istarte, llgeom%icounte )
280 call llgeom%bump%delete()
294 type(fckit_configuration),
intent(in) :: f_conf
295 type(datetime),
intent(in) :: vdate
298 integer(kind=c_int) :: idate, isecs
299 character(len=64) :: datefile
301 integer :: ncid, varid(2)
302 integer :: x_dimid, y_dimid, z_dimid, e_dimid, t_dimid
303 character(len=:),
allocatable :: str
306 call datetime_to_ifs(vdate, idate, isecs)
307 date(1) = idate/10000
308 date(2) = idate/100 - date(1)*100
309 date(3) = idate - (date(1)*10000 + date(2)*100)
311 date(5) = (isecs - date(4)*3600)/60
312 date(6) = isecs - (date(4)*3600 + date(5)*60)
315 llgeom%filename =
'Data/fv3jedi.latlon.'
316 if (f_conf%has(
"filename"))
then
317 call f_conf%get_or_die(
"filename",str)
318 llgeom%filename = str
323 write(datefile,
'(I4,I0.2,I0.2,A1,I0.2,I0.2,I0.2)') date(1),date(2),date(3),
"_",date(4),date(5),date(6)
324 llgeom%filename = trim(llgeom%filename)//trim(datefile)//trim(
"z.nc4")
326 call nccheck( nf90_create( llgeom%filename, ior(nf90_netcdf4, nf90_mpiio), ncid, &
327 comm = llgeom%f_comm%communicator(), info = mpi_info_null),
"nf90_create" )
330 call nccheck ( nf90_def_dim(ncid,
"lon" , llgeom%nxg , x_dimid),
"nf90_def_dim lon" )
331 call nccheck ( nf90_def_dim(ncid,
"lat" , llgeom%nyg , y_dimid),
"nf90_def_dim lat" )
332 call nccheck ( nf90_def_dim(ncid,
"lev" , geom%npz , z_dimid),
"nf90_def_dim lev" )
333 call nccheck ( nf90_def_dim(ncid,
"edge", geom%npz+1 , e_dimid),
"nf90_def_dim lev" )
334 call nccheck ( nf90_def_dim(ncid,
"time", 1 , t_dimid),
"nf90_def_dim time" )
337 call nccheck( nf90_def_var(ncid,
"lons", nf90_double, x_dimid, varid(1)),
"nf90_def_var lons" )
338 call nccheck( nf90_def_var(ncid,
"lats", nf90_double, y_dimid, varid(2)),
"nf90_def_var lats" )
340 call nccheck( nf90_enddef(ncid),
"nf90_enddef" )
342 if (llgeom%thispe)
then
345 call nccheck( nf90_put_var( ncid, varid(1), llgeom%lons, &
346 start = llgeom%istart2(1:1), count = llgeom%icount2(1:1) ),
"nf90_put_var lons" )
347 call nccheck( nf90_put_var( ncid, varid(2), llgeom%lats, &
348 start = llgeom%istart2(2:2), count = llgeom%icount2(2:2) ),
"nf90_put_var lats" )
353 call nccheck( nf90_close(ncid),
"nf90_close" )
356 call llgeom%f_comm%barrier()
371 integer :: var, ji, jj, jk, csngrid, llngrid, ii, i, j, k, n
372 real(kind=
kind_real),
allocatable :: llfield_bump(:,:)
373 real(kind=
kind_real),
allocatable :: llfield(:,:,:)
375 integer :: ncid, varid
376 integer :: x_dimid, y_dimid, z_dimid, e_dimid, t_dimid
377 integer,
target :: dimids3(4), dimids2(3), dimidse(4)
378 integer,
pointer :: dimids(:), istart(:), icount(:)
382 do var = 1,
size(fields)
386 if ( trim(fields(var)%space) ==
'magnitude' .and. &
387 trim(fields(var)%staggerloc) ==
'center' .and. &
388 .not. fields(var)%integerfield )
then
392 if (llgeom%thispe)
then
393 allocate(llfield(1:llgeom%nx,1:llgeom%ny,1:geom%npz))
395 allocate(llfield(0,0,0))
397 llfield = 0.0_kind_real
399 csngrid = (geom%iec-geom%isc+1)*(geom%jec-geom%jsc+1)
400 llngrid = llgeom%nx*llgeom%ny
403 allocate(llfield_bump(llngrid,geom%npz))
406 call llgeom%bump%apply(geom%npz, fields(var)%array, llngrid, llfield_bump)
409 if (llgeom%thispe)
then
415 llfield(ji,jj,jk) = llfield_bump(ii,jk)
422 call nccheck( nf90_open( llgeom%filename, ior(nf90_write, nf90_mpiio), ncid, &
423 comm = llgeom%f_comm%communicator(), info = mpi_info_null),
"nf90_open" )
426 call nccheck( nf90_inq_dimid(ncid,
"lon" , x_dimid),
"nf90_inq_dimid lon" )
427 call nccheck( nf90_inq_dimid(ncid,
"lat" , y_dimid),
"nf90_inq_dimid lat" )
428 call nccheck( nf90_inq_dimid(ncid,
"lev" , z_dimid),
"nf90_inq_dimid lev" )
429 call nccheck( nf90_inq_dimid(ncid,
"edge", e_dimid),
"nf90_inq_dimid edge" )
430 call nccheck( nf90_inq_dimid(ncid,
"time", t_dimid),
"nf90_inq_dimid time" )
432 dimids3 = (/ x_dimid, y_dimid, z_dimid, t_dimid /)
433 dimidse = (/ x_dimid, y_dimid, e_dimid, t_dimid /)
434 dimids2 = (/ x_dimid, y_dimid, t_dimid /)
437 if (
associated(dimids))
nullify(dimids)
438 if (
associated(istart))
nullify(istart)
439 if (
associated(icount))
nullify(icount)
440 if (fields(var)%npz == geom%npz)
then
442 istart => llgeom%istart3
443 icount => llgeom%icount3
444 elseif (fields(var)%npz == 1)
then
446 istart => llgeom%istart2
447 icount => llgeom%icount2
448 elseif (fields(var)%npz == geom%npz+1)
then
450 istart => llgeom%istarte
451 icount => llgeom%icounte
454 if (
associated(dimids))
then
457 call nccheck( nf90_def_var( ncid, trim(fields(var)%short_name), nf90_double, dimids, varid), &
458 "nf90_def_var"//trim(fields(var)%short_name) )
459 call nccheck( nf90_put_att(ncid, varid,
"long_name", trim(fields(var)%long_name) ),
"nf90_put_att" )
460 call nccheck( nf90_put_att(ncid, varid,
"units" , trim(fields(var)%units) ),
"nf90_put_att" )
461 call nccheck( nf90_enddef(ncid),
"nf90_enddef" )
463 if (llgeom%thispe)
then
464 call nccheck( nf90_put_var( ncid, varid, llfield, start = istart, count = icount), &
465 "nf90_put_var"//trim(fields(var)%short_name) )
471 call nccheck( nf90_close(ncid),
"nf90_close" )
474 call llgeom%f_comm%barrier()
477 deallocate(llfield_bump)