ocnice_prep  1.13.0
All Data Structures Files Functions Variables Pages
ocniceprep.F90
Go to the documentation of this file.
1 
6 
18 program ocniceprep
19 
20  use esmf
21  use netcdf
22  use init_mod , only : nxt, nyt, nlevs, nxr, nyr, outvars, readnml, readcsv
23  use init_mod , only : wgtsdir, griddir, ftype, fsrc, fdst, input_file, maskvar
24  use init_mod , only : do_ocnprep, debug, logunit
25  use arrays_mod , only : b2d, c2d, b3d, rgb2d, rgb3d, rgc2d, setup_packing
26  use arrays_mod , only : nbilin2d, nbilin3d, nconsd2d, bilin2d, bilin3d, consd2d
27  use arrays_mod , only : mask3d, hmin, maskspval, eta
28  use utils_mod , only : getfield, packarrays, remap, dumpnc, nf90_err
29  use utils_esmf_mod , only : createrh, remaprh, chkerr, rotremap
30  use restarts_mod , only : setup_icerestart, setup_ocnrestart
31  use ocncalc_mod , only : calc_eta, vfill
32 
33  implicit none
34 
35  type(esmf_vm) :: vm
36  character(len=160) :: gridfile
37  character(len=160) :: wgtsfile
38  character(len=160) :: fout
39 
40  real(kind=8), allocatable, dimension(:) :: angsrc
41  real(kind=8), allocatable, dimension(:) :: angdst
42 
43  real(kind=8), allocatable, dimension(:) :: bathysrc
44  real(kind=8), allocatable, dimension(:) :: bathydst
45 
46  ! work arrays for output netcdf
47  real(kind=8), allocatable, dimension(:,:) :: out2d
48  real(kind=8), allocatable, dimension(:,:,:) :: out3d
49 
50  character(len=120) :: errmsg
51  character(len=120) :: meshfsrc, meshfdst
52  integer :: nvalid
53  integer :: k,n,nn,rc,ncid,varid
54  character(len=20) :: vname
55  ! debug
56  integer :: i,j
57 
58  character(len=*), parameter :: u_file_u = __file__
59 
60  ! -----------------------------------------------------------------------------
61  ! initialize ESMF
62  ! -----------------------------------------------------------------------------
63 
64  call esmf_initialize(rc=rc)
65  if (chkerr(rc,__line__,u_file_u)) call esmf_finalize(endflag=esmf_end_abort)
66  call esmf_vmgetglobal(vm, rc=rc)
67  if (chkerr(rc,__line__,u_file_u)) call esmf_finalize(endflag=esmf_end_abort)
68 
69  ! -----------------------------------------------------------------------------
70  ! read the nml file and a file containing the list of variables to be remapped
71  ! -----------------------------------------------------------------------------
72 
73  call readnml('ocniceprep.nml',errmsg,rc)
74  if (rc /= 0) then
75  write(0,'(a)')trim(errmsg)
76  stop
77  else
78  write(logunit,'(a)')trim(errmsg)
79  end if
80 
81  call readcsv(trim(ftype)//'.csv',errmsg,rc,nvalid)
82  if (rc /= 0) then
83  write(0,'(a)')trim(errmsg)
84  stop
85  else
86  write(logunit,'(a)')trim(errmsg)
87  end if
88 
89  ! -----------------------------------------------------------------------------
90  ! create a regrid RH from source to destination
91  ! -----------------------------------------------------------------------------
92 
93  meshfsrc = trim(griddir)//fsrc(3:5)//'/'//'mesh.'//trim(fsrc)//'.nc'
94  meshfdst = trim(griddir)//fdst(3:5)//'/'//'mesh.'//trim(fdst)//'.nc'
95  write(logunit,'(a)')'mesh src: '//trim(meshfsrc)
96  write(logunit,'(a)')'mesh dst: '//trim(meshfdst)
97  call createrh(trim(meshfsrc),trim(meshfdst),rc=rc)
98  if (chkerr(rc,__line__,u_file_u)) call esmf_finalize(endflag=esmf_end_abort)
99 
100  ! -----------------------------------------------------------------------------
101  ! read the master grid file and obtain the rotation angle on the source and
102  ! destination grids
103  ! -----------------------------------------------------------------------------
104 
105  allocate(angsrc(nxt*nyt)); angsrc = 0.0
106  allocate(angdst(nxr*nyr)); angdst = 0.0
107  allocate(bathysrc(nxt*nyt)); bathysrc = 0.0
108  allocate(bathydst(nxr*nyr)); bathydst = 0.0
109 
110  gridfile = trim(griddir)//fsrc(3:5)//'/'//'tripole.'//trim(fsrc)//'.nc'
111  call nf90_err(nf90_open(trim(gridfile), nf90_nowrite, ncid), &
112  'open: '//trim(gridfile))
113  call getfield(trim(gridfile), 'anglet', dims=(/nxt,nyt/), field=angsrc)
114  call getfield(trim(gridfile), 'depth', dims=(/nxt,nyt/), field=bathysrc)
115  call nf90_err(nf90_close(ncid), 'close: '//trim(gridfile))
116 
117  gridfile = trim(griddir)//fdst(3:5)//'/'//'tripole.'//trim(fdst)//'.nc'
118  call nf90_err(nf90_open(trim(gridfile), nf90_nowrite, ncid), &
119  'open: '//trim(gridfile))
120  call getfield(trim(gridfile), 'anglet', dims=(/nxr,nyr/), field=angdst)
121  call getfield(trim(gridfile), 'depth', dims=(/nxr,nyr/), field=bathydst)
122  call nf90_err(nf90_close(ncid), 'close: '//trim(gridfile))
123 
124  ! -----------------------------------------------------------------------------
125  ! get the 3rd (vertical or ncat) dimension and variable attributes for the
126  ! ocean file
127  ! -----------------------------------------------------------------------------
128 
129  call nf90_err(nf90_open(trim(input_file), nf90_nowrite, ncid), &
130  'open: '//trim(input_file))
131  if (do_ocnprep) then
132  call nf90_err(nf90_inq_dimid(ncid, 'Layer', varid), &
133  'get dimension Id: Layer'//trim(input_file))
134  call nf90_err(nf90_inquire_dimension(ncid, varid, len=nlevs), &
135  'get dimension Id: Layer'//trim(input_file))
136  else
137  call nf90_err(nf90_inq_dimid(ncid, 'ncat', varid), &
138  'get dimension Id: ncat'//trim(input_file))
139  call nf90_err(nf90_inquire_dimension(ncid, varid, len=nlevs), &
140  'get dimension Id: ncat'//trim(input_file))
141  endif
142  do n = 1,nvalid
143  if (do_ocnprep) then
144  if (trim(outvars(n)%var_name) .eq. 'eta')then
145  outvars(n)%long_name = 'Interface height'
146  outvars(n)%units = 'm'
147  else
148  call nf90_err(nf90_inq_varid(ncid, trim(outvars(n)%var_name), varid), &
149  'get variable Id: '//trim(outvars(n)%var_name))
150  call nf90_err(nf90_get_att(ncid, varid, 'long_name', outvars(n)%long_name), &
151  'get variable attribute: long_name '//trim(outvars(n)%var_name))
152  call nf90_err(nf90_get_att(ncid, varid, 'units', outvars(n)%units), &
153  'get variable attribute: units '//trim(outvars(n)%var_name) )
154  end if
155  end if
156  end do
157  call nf90_err(nf90_close(ncid), 'close: '//trim(input_file))
158 
159  if (debug) then
160  do n = 1,nvalid
161  write(logunit,'(i4,a14,i4,a10,3(a6),a2)')n,' '//trim(outvars(n)%var_name)// &
162  ', ', outvars(n)%var_dimen,', '//trim(outvars(n)%var_remapmethod), &
163  ', '//trim(outvars(n)%var_grid), ', '//trim(outvars(n)%var_pair), &
164  ', '//trim(outvars(n)%var_pair_grid)
165  end do
166  end if
167 
168  ! -----------------------------------------------------------------------------
169  ! get the masking variable for ocean 3-d remapping and create the mask
170  ! -----------------------------------------------------------------------------
171 
172  if (do_ocnprep) then
173  allocate(eta(nlevs,nxt*nyt)); eta=0.0
174  call calc_eta(trim(input_file),(/nxt,nyt,nlevs/),bathysrc)
175 
176  allocate(mask3d(nlevs,nxt*nyt)); mask3d = 0.0
177  call getfield(trim(input_file), trim(maskvar), dims=(/nxt,nyt,nlevs/), field=mask3d)
178  where(mask3d .le. real(hmin,4))mask3d = hmin
179 
180  where(mask3d .le. hmin)mask3d = maskspval
181  where(mask3d .ne. maskspval)mask3d = 1.0
182 
183  if (debug) then
184  call dumpnc(trim(ftype)//'.'//trim(fsrc)//'.eta.nc', 'eta', &
185  dims=(/nxt,nyt,nlevs/), field=eta)
186  call dumpnc(trim(ftype)//'.'//trim(fsrc)//'.mask3d.nc', 'mask3d', &
187  dims=(/nxt,nyt,nlevs/), field=mask3d)
188  end if
189  end if
190 
191  ! -----------------------------------------------------------------------------
192  ! create packed arrays for mapping and remap arrays to the destination grid
193  ! -----------------------------------------------------------------------------
194 
195  call setup_packing(nvalid,outvars)
196 
197  ! 2D bilin
198  if (allocated(bilin2d)) then
199  call packarrays(trim(input_file), trim(wgtsdir)//fsrc(3:5)//'/', &
200  cos(angsrc), sin(angsrc), b2d, dims=(/nxt,nyt/), nflds=nbilin2d, fields=bilin2d)
201  rgb2d = 0.0
202  call remaprh(src_field=bilin2d, dst_field=rgb2d,rc=rc)
203  if (chkerr(rc,__line__,u_file_u)) call esmf_finalize(endflag=esmf_end_abort)
204 
205  if (debug) then
206  write(logunit,'(a)')'remap 2D fields bilinear with RH '
207  write(logunit,'(a)')'packed min/max values, mapped min/max values'
208  do n = 1,nbilin2d
209  write(logunit,'(i4,a14,3(a2,a6),4g14.4)')n,' '// &
210  trim(b2d(n)%var_name),' ',trim(b2d(n)%var_grid),' ', &
211  trim(b2d(n)%var_pair),' ',trim(b2d(n)%var_pair_grid), &
212  minval(bilin2d(n,:)), maxval(bilin2d(n,:)), &
213  minval(rgb2d(n,:)), maxval(rgb2d(n,:))
214  end do
215  call dumpnc(trim(ftype)//'.'//trim(fsrc)//'.bilin2d.nc', 'bilin2d', &
216  dims=(/nxt,nyt/), nflds=nbilin2d, field=bilin2d)
217  call dumpnc(trim(ftype)//'.'//trim(fdst)//'.rgbilin2d.nc', 'rgbilin2d', &
218  dims=(/nxr,nyr/), nflds=nbilin2d, field=rgb2d)
219  end if
220  end if
221 
222  ! 2D conserv
223  if (allocated(consd2d)) then
224  call packarrays(trim(input_file), trim(wgtsdir)//fsrc(3:5)//'/', &
225  cos(angsrc), sin(angsrc), c2d, dims=(/nxt,nyt/), nflds=nconsd2d, fields=consd2d)
226  rgc2d = 0.0
227  call remaprh(src_field=consd2d, dst_field=rgc2d,rc=rc)
228  if (chkerr(rc,__line__,u_file_u)) call esmf_finalize(endflag=esmf_end_abort)
229 
230  if (debug) then
231  write(logunit,'(a)')'remap 2D fields conserv with RH '
232  write(logunit,'(a)')'packed min/max values, mapped min/max values'
233  do n = 1,nconsd2d
234  write(logunit,'(i4,a14,3(a2,a6),4g14.4)')n,' '// &
235  trim(c2d(n)%var_name),' ', trim(c2d(n)%var_grid),' ', &
236  trim(c2d(n)%var_pair),' ', trim(c2d(n)%var_pair_grid), &
237  minval(consd2d(n,:)), maxval(consd2d(n,:)), &
238  minval(rgc2d(n,:)), maxval(rgc2d(n,:))
239  end do
240  call dumpnc(trim(ftype)//'.'//trim(fsrc)//'.consd2d.nc', 'consd2d', &
241  dims=(/nxt,nyt/), nflds=nconsd2d, field=consd2d)
242  call dumpnc(trim(ftype)//'.'//trim(fdst)//'.rgconsd2d.nc', 'rgconsd2d', &
243  dims=(/nxr,nyr/), nflds=nconsd2d, field=rgc2d)
244  end if
245  end if
246 
247  ! 3D bilin
248  if (allocated(bilin3d))then
249  call packarrays(trim(input_file), trim(wgtsdir)//fsrc(3:5)//'/', &
250  cos(angsrc), sin(angsrc), b3d, dims=(/nxt,nyt,nlevs/), nflds=nbilin3d, fields=bilin3d)
251  rgb3d = 0.0
252  do k = 1,nlevs
253  if (do_ocnprep) then
254  call remaprh(k,src_field=bilin3d(:,k,:), dst_field=rgb3d(:,k,:), hmask=mask3d(k,:),rc=rc)
255  if (chkerr(rc,__line__,u_file_u)) call esmf_finalize(endflag=esmf_end_abort)
256  else
257  call remaprh(src_field=bilin3d(:,k,:), dst_field=rgb3d(:,k,:),rc=rc)
258  if (chkerr(rc,__line__,u_file_u)) call esmf_finalize(endflag=esmf_end_abort)
259  end if
260  end do
261  if (do_ocnprep) then
262  call vfill()
263  end if
264 
265  if (debug) then
266  write(logunit,'(a)')'remap 3D fields bilinear with RH '
267  write(logunit,'(a)')'packed min/max values,mapped min/max values'
268  do n = 1,nbilin3d
269  write(logunit,'(i4,a14,3(a2,a6),4g14.4)')n,' '// &
270  trim(b3d(n)%var_name),' ', trim(b3d(n)%var_grid),' ', &
271  trim(b3d(n)%var_pair),' ', trim(b3d(n)%var_pair_grid), &
272  minval(bilin3d(n,:,:)), maxval(bilin3d(n,:,:)), &
273  minval(rgb3d(n,:,:)), maxval(rgb3d(n,:,:))
274  end do
275  call dumpnc(trim(ftype)//'.'//trim(fsrc)//'.bilin3d.nc', 'bilin3d', &
276  dims=(/nxt,nyt,nlevs/), nk=nlevs, nflds=nbilin3d, field=bilin3d)
277  call dumpnc(trim(ftype)//'.'//trim(fdst)//'.rgbilin3d.nc', 'rgbilin3d', &
278  dims=(/nxr,nyr,nlevs/), nk=nlevs, nflds=nbilin3d, field=rgb3d)
279  end if
280  end if
281 
282  !------------------------------------------------------------------------------
283  ! rotate on Ct from EN->IJ and remap back to native staggers
284  !------------------------------------------------------------------------------
285 
286  if (allocated(bilin2d)) then
287  call rotremap(trim(wgtsdir)//fdst(3:5)//'/', b2d, cos(angdst), sin(angdst), &
288  dims=(/nxr,nyr/), nflds=nbilin2d, fields=rgb2d)
289  if (debug) then
290  call dumpnc(trim(ftype)//'.'//trim(fdst)//'.rgbilin2d.ij.nc', 'rgbilin2d', &
291  dims=(/nxr,nyr/), nflds=nbilin2d, field=rgb2d)
292  end if
293  end if
294  if (allocated(consd2d)) then
295  call rotremap(trim(wgtsdir)//fdst(3:5)//'/', c2d, cos(angdst), sin(angdst), &
296  dims=(/nxr,nyr/), nflds=nconsd2d, fields=rgc2d)
297  if (debug) then
298  call dumpnc(trim(ftype)//'.'//trim(fdst)//'.rgbilin2d.ij.nc', 'rgbilin2d', &
299  dims=(/nxr,nyr/), nflds=nconsd2d, field=rgc2d)
300  end if
301  end if
302  if (allocated(bilin3d)) then
303  call rotremap(trim(wgtsdir)//fdst(3:5)//'/', b3d, cos(angdst), sin(angdst), &
304  dims=(/nxr,nyr,nlevs/), nflds=nbilin3d, fields=rgb3d)
305  if (debug) then
306  call dumpnc(trim(ftype)//'.'//trim(fdst)//'.rgbilin3d.ij.nc', 'rgbilin3d', &
307  dims=(/nxr,nyr,nlevs/), nk=nlevs, nflds=nbilin3d, field=rgb3d)
308  end if
309  end if
310 
311  ! -----------------------------------------------------------------------------
312  ! write the mapped fields
313  ! -----------------------------------------------------------------------------
314 
315  allocate(out2d(nxr,nyr)); out2d = 0.0
316  allocate(out3d(nxr,nyr,nlevs)); out3d = 0.0
317 
318  fout = trim(ftype)//'.'//trim(fdst)//'.nc'
319  if (debug) write(logunit, '(a)')'output file: '//trim(fout)
320 
321  if (do_ocnprep) then
322  call setup_ocnrestart(trim(input_file),trim(fout),bathydst)
323  else
324  call setup_icerestart(trim(input_file),trim(fout))
325  end if
326 
327  call nf90_err(nf90_open(trim(fout), nf90_write, ncid), 'write: '//trim(fout))
328  if (allocated(rgb2d)) then
329  do n = 1,nbilin2d
330  out2d(:,:) = reshape(rgb2d(n,:), (/nxr,nyr/))
331  if (b2d(n)%var_grid(1:2) == 'Bu') out2d(:,nyr) = out2d(:,nyr-1)
332  vname = trim(b2d(n)%var_name)
333  call nf90_err(nf90_inq_varid(ncid, vname, varid), 'get variable Id: '//vname)
334  call nf90_err(nf90_put_var(ncid, varid, out2d), 'put variable: '//vname)
335  end do
336  end if
337  if (allocated(rgc2d)) then
338  do n = 1,nconsd2d
339  out2d(:,:) = reshape(rgc2d(n,:), (/nxr,nyr/))
340  vname = trim(c2d(n)%var_name)
341  call nf90_err(nf90_inq_varid(ncid, vname, varid), 'get variable Id: '//vname)
342  call nf90_err(nf90_put_var(ncid, varid, out2d), 'put variable: '//vname)
343  end do
344  end if
345  if (allocated(rgb3d)) then
346  do n = 1,nbilin3d
347  do k = 1,nlevs
348  out3d(:,:,k) = reshape(rgb3d(n,k,:), (/nxr,nyr/))
349  end do
350  if (b3d(n)%var_grid(1:2) == 'Cv') out3d(:,nyr,:) = out3d(:,nyr-1,:)
351  vname = trim(b3d(n)%var_name)
352  call nf90_err(nf90_inq_varid(ncid, vname, varid), 'get variable Id: '//vname)
353  call nf90_err(nf90_put_var(ncid, varid, out3d), 'put variable: '//vname)
354  end do
355  end if
356  call nf90_err(nf90_close(ncid), 'close: '// trim(fout))
357  write(logunit,'(a)')trim(fout)//' done'
358  stop
359 
360 end program ocniceprep
program ocniceprep
Read either a MOM6 or CICE6 restart file at 1/4deg tripole resolution and remap the required fields t...
Definition: ocniceprep.F90:18