FV3 Bundle
fv3/fv3jedi_model_mod.f90
Go to the documentation of this file.
1 ! (C) Copyright 2017-2018 UCAR
2 !
3 ! This software is licensed under the terms of the Apache Licence Version 2.0
4 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5 
7 
8 use iso_c_binding
9 use config_mod
10 use datetime_mod
11 use duration_mod
12 use netcdf
13 
18 
20 
21 implicit none
22 private
23 
24 public :: fv3jedi_model
25 public :: model_create
26 public :: model_delete
27 public :: model_initialize
28 public :: model_step
29 public :: model_finalize
30 
31 ! ------------------------------------------------------------------------------
32 
33 !> Fortran derived type to hold model definition
35  type(fv3jedi_lm_type) :: fv3jedi_lm !<Linearized model object
36  integer :: readtraj !<Read trajectory from file
37  character(len=255) :: trajpath !<User specified path to traj files
38  character(len=255) :: trajfile !<User specified path to traj files
39 end type fv3jedi_model
40 
41 ! ------------------------------------------------------------------------------
42 
43 contains
44 
45 ! ------------------------------------------------------------------------------
46 
47 subroutine model_create(self, geom, c_conf)
48 
49 implicit none
50 type(c_ptr), intent(in) :: c_conf
51 type(fv3jedi_model), intent(inout) :: self
52 type(fv3jedi_geom), intent(in) :: geom
53 
54 !Locals
55 character(len=20) :: ststep
56 type(duration) :: dtstep
57 real(kind=kind_real) :: dt
58 
59 
60 ! Model time step
61 ! ---------------
62 ststep = config_get_string(c_conf,len(ststep),"tstep")
63 dtstep = trim(ststep)
64 dt = real(duration_seconds(dtstep),kind_real)
65 
66 
67 ! Option to read traj from file instead of propagating model
68 ! ----------------------------------------------------------
69 self%readtraj = config_get_int(c_conf,"readtraj")
70 if (self%readtraj == 1) then
71  self%trajpath = config_get_string(c_conf,len(self%trajpath),"trajpath")
72  self%trajfile = config_get_string(c_conf,len(self%trajfile),"trajfile")
73 endif
74 
75 
76 ! Model configuration and creation
77 ! --------------------------------
78 self%fv3jedi_lm%conf%do_dyn = config_get_int(c_conf,"lm_do_dyn")
79 self%fv3jedi_lm%conf%do_phy_trb = config_get_int(c_conf,"lm_do_trb")
80 self%fv3jedi_lm%conf%do_phy_mst = config_get_int(c_conf,"lm_do_mst")
81 
82 call self%fv3jedi_lm%create(dt,geom%npx,geom%npy,geom%npz,geom%ptop,geom%ak,geom%bk)
83 
84 
85 ! Safety checks
86 ! -------------
87 
88 !The full trajecotory of the tlm/adm is not output by this simplified model
89 !so if being used to generate the trajectry with physics the traj must be read
90 !from file or obtained by running GEOS or GFS.
91 if ((self%fv3jedi_lm%conf%do_phy_trb .ne. 0 .and. self%readtraj == 0) .or. &
92  (self%fv3jedi_lm%conf%do_phy_mst .ne. 0 .and. self%readtraj == 0) ) then
93  call abor1_ftn("fv3jedi_model | FV3 : unless reading the trajecotory physics should be off")
94 endif
95 
96 end subroutine model_create
97 
98 ! ------------------------------------------------------------------------------
99 
100 subroutine model_delete(self)
102 implicit none
103 type(fv3jedi_model), intent(inout) :: self
104 
105 !Delete the model
106 !----------------
107 call self%fv3jedi_lm%delete()
108 
109 end subroutine model_delete
110 
111 ! ------------------------------------------------------------------------------
112 
113 subroutine model_initialize(self, state)
115 implicit none
116 type(fv3jedi_model), intent(inout) :: self
117 type(fv3jedi_state), intent(in) :: state
118 
119 call self%fv3jedi_lm%init_nl()
120 
121 end subroutine model_initialize
122 
123 ! ------------------------------------------------------------------------------
124 
125 subroutine model_step(self, state, vdate)
127 implicit none
128 type(fv3jedi_model), intent(inout) :: self
129 type(fv3jedi_state), intent(inout) :: state
130 type(datetime), intent(in) :: vdate !< Valid datetime after step
131 
132 character(len=20) :: vdatec
133 
134 if (self%readtraj == 0) then
135 
136  call state_to_lm(state,self%fv3jedi_lm)
137  call self%fv3jedi_lm%step_nl()
138  call lm_to_state(self%fv3jedi_lm,state)
139 
140 else
141 
142  call datetime_to_string(vdate, vdatec)
143  call read_state( self, state, vdatec)
144 
145 endif
146 
147 end subroutine model_step
148 
149 ! ------------------------------------------------------------------------------
150 
151 subroutine model_finalize(self, state)
153 implicit none
154 type(fv3jedi_model), target :: self
155 type(fv3jedi_state) :: state
156 
157 call self%fv3jedi_lm%final_nl()
158 
159 end subroutine model_finalize
160 
161 ! ------------------------------------------------------------------------------
162 
163 subroutine state_to_lm( state, lm )
165 implicit none
166 type(fv3jedi_state), intent(in) :: state
167 type(fv3jedi_lm_type), intent(inout) :: lm
168 
169 lm%traj%u = state%ud
170 lm%traj%v = state%vd
171 lm%traj%ua = state%ua
172 lm%traj%va = state%va
173 lm%traj%t = state%t
174 lm%traj%delp = state%delp
175 lm%traj%qv = state%q
176 lm%traj%qi = state%qi
177 lm%traj%ql = state%ql
178 lm%traj%o3 = state%o3
179 
180 if (.not. lm%conf%hydrostatic) then
181 lm%traj%w = state%w
182 lm%traj%delz = state%delz
183 endif
184 
185 lm%traj%phis = state%phis
186 
187 end subroutine state_to_lm
188 
189 ! ------------------------------------------------------------------------------
190 
191 subroutine lm_to_state( lm, state )
193 implicit none
194 type(fv3jedi_lm_type), intent(in) :: lm
195 type(fv3jedi_state), intent(inout) :: state
196 
197 state%ud = lm%traj%u
198 state%vd = lm%traj%v
199 state%ua = lm%traj%ua
200 state%va = lm%traj%va
201 state%t = lm%traj%t
202 state%delp = lm%traj%delp
203 state%q = lm%traj%qv
204 state%qi = lm%traj%qi
205 state%ql = lm%traj%ql
206 state%o3 = lm%traj%o3
207 
208 if (.not. lm%conf%hydrostatic) then
209 state%w = lm%traj%w
210 state%delz = lm%traj%delz
211 endif
212 
213 state%phis = lm%traj%phis
214 
215 end subroutine lm_to_state
216 
217 ! ------------------------------------------------------------------------------
218 
219 subroutine read_state( self, state, vdatec)
221 implicit none
222 type(fv3jedi_model), intent(in) :: self
223 type(fv3jedi_state), intent(inout) :: state
224 character(len=20), intent(in) :: vdatec
225 
226 character(len=255) :: date, path, fname1, fname2, filename
227 character(len=4) :: yyyy,mm,dd,hh,mn
228 character(len=20) :: var
229 integer, allocatable :: istart(:), icount(:)
230 integer :: ncid, ncstat, dimid, varid
231 integer :: im, jm
232 
233 integer :: tileoff
234 logical :: tiledimension = .false.
235 
236 integer :: isc,iec,jsc,jec
237 
238 write(date,*) vdatec(1:4),vdatec(6:7),vdatec(9:10),'_',vdatec(12:13),vdatec(15:16),'z.nc4'
239 
240 isc = state%isc
241 iec = state%iec
242 jsc = state%jsc
243 jec = state%jec
244 
245 path = self%trajpath
246 fname1 = self%trajfile
247 
248 !> Build filename
249 yyyy = vdatec(1 :4 )
250 mm = vdatec(6 :7 )
251 dd = vdatec(9 :10)
252 hh = vdatec(12:13)
253 mn = vdatec(15:16)
254 fname2 = 'z.nc4'
255 
256 filename = trim(path)//trim(fname1)//trim(yyyy)//trim(mm)//trim(dd)//"_"//trim(hh)//trim(mn)//trim(fname2)
257 
258 if (self%fv3jedi_lm%conf%rpe) print*, ' '
259 if (self%fv3jedi_lm%conf%rpe) print*, 'Reading trajectory: ', trim(filename)
260 if (self%fv3jedi_lm%conf%rpe) print*, ' '
261 
262 !> Open the file
263 ncstat = nf90_open(trim(filename), nf90_nowrite, ncid)
264 if(ncstat /= nf90_noerr) print *, "OPEN: "//trim(nf90_strerror(ncstat))
265 
266 !> Get dimensions, lon,lat
267 ncstat = nf90_inq_dimid(ncid, "lon", dimid)
268 if(ncstat /= nf90_noerr) print *, "lon: "//trim(nf90_strerror(ncstat))
269 ncstat = nf90_inquire_dimension(ncid, dimid, len = im)
270 if(ncstat /= nf90_noerr) print *, "lon:"//trim(nf90_strerror(ncstat))
271 
272 ncstat = nf90_inq_dimid(ncid, "lat", dimid)
273 if(ncstat /= nf90_noerr) print *, "lat: "//trim(nf90_strerror(ncstat))
274 ncstat = nf90_inquire_dimension(ncid, dimid, len = jm)
275 if(ncstat /= nf90_noerr) print *, "lat: "//trim(nf90_strerror(ncstat))
276 
277 !> GEOS can use concatenated tiles or tile as a dimension
278 if ( (im == state%npx-1) .and. (jm == 6*(state%npy-1) ) ) then
279  tiledimension = .false.
280  tileoff = (state%ntile-1)*(jm/state%ntiles)
281 else
282  tiledimension = .true.
283  tileoff = 0
284  call abor1_ftn("Trajectory GEOS: tile dimension in file not done yet")
285 endif
286 
287 allocate(istart(4))
288 allocate(icount(4))
289 istart(1) = isc
290 istart(2) = tileoff + jsc
291 istart(3) = 1
292 istart(4) = 1
293 
294 icount(1) = iec-isc+1
295 icount(2) = jec-jsc+1
296 icount(3) = 72
297 icount(4) = 1
298 
299 var = 'ud'
300 ncstat = nf90_inq_varid(ncid, trim(var), varid)
301 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
302 ncstat = nf90_get_var(ncid, varid, state%ud(isc:iec,jsc:jec,:), istart, icount)
303 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
304 
305 var = 'vd'
306 ncstat = nf90_inq_varid(ncid, trim(var), varid)
307 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
308 ncstat = nf90_get_var(ncid, varid, state%vd(isc:iec,jsc:jec,:), istart, icount)
309 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
310 
311 var = 'ua'
312 ncstat = nf90_inq_varid(ncid, trim(var), varid)
313 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
314 ncstat = nf90_get_var(ncid, varid, state%ua(isc:iec,jsc:jec,:), istart, icount)
315 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
316 
317 var = 'va'
318 ncstat = nf90_inq_varid(ncid, trim(var), varid)
319 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
320 ncstat = nf90_get_var(ncid, varid, state%va(isc:iec,jsc:jec,:), istart, icount)
321 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
322 
323 var = 't'
324 ncstat = nf90_inq_varid(ncid, trim(var), varid)
325 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
326 ncstat = nf90_get_var(ncid, varid, state%t(isc:iec,jsc:jec,:), istart, icount)
327 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
328 
329 var = 'delp'
330 ncstat = nf90_inq_varid(ncid, trim(var), varid)
331 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
332 ncstat = nf90_get_var(ncid, varid, state%delp(isc:iec,jsc:jec,:), istart, icount)
333 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
334 
335 var = 'q'
336 ncstat = nf90_inq_varid(ncid, trim(var), varid)
337 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
338 ncstat = nf90_get_var(ncid, varid, state%q(isc:iec,jsc:jec,:), istart, icount)
339 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
340 
341 var = 'qi'
342 ncstat = nf90_inq_varid(ncid, trim(var), varid)
343 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
344 ncstat = nf90_get_var(ncid, varid, state%qi(isc:iec,jsc:jec,:), istart, icount)
345 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
346 
347 var = 'ql'
348 ncstat = nf90_inq_varid(ncid, trim(var), varid)
349 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
350 ncstat = nf90_get_var(ncid, varid, state%ql(isc:iec,jsc:jec,:), istart, icount)
351 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
352 
353 var = 'o3mr'
354 ncstat = nf90_inq_varid(ncid, trim(var), varid)
355 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
356 ncstat = nf90_get_var(ncid, varid, state%o3(isc:iec,jsc:jec,:), istart, icount)
357 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
358 
359 if (.not.self%fv3jedi_lm%conf%hydrostatic) then
360 
361  var = 'w'
362  ncstat = nf90_inq_varid(ncid, trim(var), varid)
363  if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
364  ncstat = nf90_get_var(ncid, varid, state%w(isc:iec,jsc:jec,:), istart, icount)
365  if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
366 
367  var = 'delz'
368  ncstat = nf90_inq_varid(ncid, trim(var), varid)
369  if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
370  ncstat = nf90_get_var(ncid, varid, state%delz(isc:iec,jsc:jec,:), istart, icount)
371  if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
372 
373 endif
374 
375 if (self%fv3jedi_lm%conf%do_phy_mst .ne. 0) then
376 
377  var = 'qls'
378  ncstat = nf90_inq_varid(ncid, trim(var), varid)
379  if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
380  ncstat = nf90_get_var(ncid, varid, state%qls(isc:iec,jsc:jec,:), istart, icount)
381  if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
382 
383  var = 'qcn'
384  ncstat = nf90_inq_varid(ncid, trim(var), varid)
385  if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
386  ncstat = nf90_get_var(ncid, varid, state%qcn(isc:iec,jsc:jec,:), istart, icount)
387  if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
388 
389  var = 'cfcn'
390  ncstat = nf90_inq_varid(ncid, trim(var), varid)
391  if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
392  ncstat = nf90_get_var(ncid, varid, state%cfcn(isc:iec,jsc:jec,:), istart, icount)
393  if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
394 
395 endif
396 
397 deallocate(istart,icount)
398 
399 allocate(istart(3))
400 allocate(icount(3))
401 istart(1) = isc
402 istart(2) = tileoff + jsc
403 istart(3) = 1
404 
405 icount(1) = iec-isc+1
406 icount(2) = jec-jsc+1
407 icount(3) = 1
408 
409 var = 'phis'
410 ncstat = nf90_inq_varid(ncid, trim(var), varid)
411 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
412 ncstat = nf90_get_var(ncid, varid, state%phis(isc:iec,jsc:jec), istart, icount)
413 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
414 
415 var = 'frocean'
416 ncstat = nf90_inq_varid(ncid, trim(var), varid)
417 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
418 ncstat = nf90_get_var(ncid, varid, state%frocean(isc:iec,jsc:jec), istart, icount)
419 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
420 
421 var = 'frland'
422 ncstat = nf90_inq_varid(ncid, trim(var), varid)
423 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
424 ncstat = nf90_get_var(ncid, varid, state%frland(isc:iec,jsc:jec), istart, icount)
425 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
426 
427 var = 'varflt'
428 ncstat = nf90_inq_varid(ncid, trim(var), varid)
429 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
430 ncstat = nf90_get_var(ncid, varid, state%varflt(isc:iec,jsc:jec), istart, icount)
431 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
432 
433 var = 'ustar'
434 ncstat = nf90_inq_varid(ncid, trim(var), varid)
435 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
436 ncstat = nf90_get_var(ncid, varid, state%ustar(isc:iec,jsc:jec), istart, icount)
437 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
438 
439 var = 'bstar'
440 ncstat = nf90_inq_varid(ncid, trim(var), varid)
441 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
442 ncstat = nf90_get_var(ncid, varid, state%bstar(isc:iec,jsc:jec), istart, icount)
443 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
444 
445 var = 'zpbl'
446 ncstat = nf90_inq_varid(ncid, trim(var), varid)
447 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
448 ncstat = nf90_get_var(ncid, varid, state%zpbl(isc:iec,jsc:jec), istart, icount)
449 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
450 
451 var = 'cm'
452 ncstat = nf90_inq_varid(ncid, trim(var), varid)
453 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
454 ncstat = nf90_get_var(ncid, varid, state%cm(isc:iec,jsc:jec), istart, icount)
455 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
456 
457 var = 'ct'
458 ncstat = nf90_inq_varid(ncid, trim(var), varid)
459 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
460 ncstat = nf90_get_var(ncid, varid, state%ct(isc:iec,jsc:jec), istart, icount)
461 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
462 
463 var = 'cq'
464 ncstat = nf90_inq_varid(ncid, trim(var), varid)
465 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
466 ncstat = nf90_get_var(ncid, varid, state%cq(isc:iec,jsc:jec), istart, icount)
467 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
468 
469 var = 'kcbl'
470 ncstat = nf90_inq_varid(ncid, trim(var), varid)
471 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
472 ncstat = nf90_get_var(ncid, varid, state%kcbl(isc:iec,jsc:jec), istart, icount)
473 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
474 
475 var = 'ts'
476 ncstat = nf90_inq_varid(ncid, trim(var), varid)
477 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
478 ncstat = nf90_get_var(ncid, varid, state%ts(isc:iec,jsc:jec), istart, icount)
479 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
480 
481 var = 'khl'
482 ncstat = nf90_inq_varid(ncid, trim(var), varid)
483 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
484 ncstat = nf90_get_var(ncid, varid, state%khl(isc:iec,jsc:jec), istart, icount)
485 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
486 
487 var = 'khu'
488 ncstat = nf90_inq_varid(ncid, trim(var), varid)
489 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
490 ncstat = nf90_get_var(ncid, varid, state%khu(isc:iec,jsc:jec), istart, icount)
491 if(ncstat /= nf90_noerr) print *, trim(var)//trim(nf90_strerror(ncstat))
492 
493 !Close this file
494 ncstat = nf90_close(ncid)
495 if(ncstat /= nf90_noerr) print *, "CLOSE: "//trim(nf90_strerror(ncstat))
496 
497 deallocate(istart,icount)
498 
499 end subroutine read_state
500 
501 ! ------------------------------------------------------------------------------
502 
503 end module fv3jedi_model_mod
Fortran derived type to hold FV3JEDI increment.
Top level for fv3jedi linearized model.
subroutine, public model_initialize(self, state)
Fortran derived type to hold FV3JEDI state.
Fortran derived type to hold geometry data for the FV3JEDI model.
subroutine lm_to_state(lm, state)
Handle state for the FV3JEDI odel.
Fortran derived type to hold model definition.
subroutine, public model_finalize(self, state)
Handle increment for the FV3JEDI model.
subroutine, public model_create(self, geom, c_conf)
Fortran module handling geometry for the FV3 model.
subroutine, public model_step(self, state, vdate)
subroutine state_to_lm(state, lm)
subroutine, public model_delete(self)
integer, parameter, public kind_real
subroutine read_state(self, state, vdatec)