fvcom_tools  1.7.0
 All Data Structures Files Functions Variables
module_nwp.f90
Go to the documentation of this file.
1 
4 
15 module module_nwp
16 
17  use kinds, only: r_kind, r_single, i_short, rmissing
18  use module_nwp_base, only: nwpbase
19 ! use module_map_utils, only: map_util
20  use module_ncio, only: ncio
21 
22  implicit none
23 
24  public :: fcst_nwp
25  public :: nwp_type
26 
27  private
28  type :: nwp_type
29  character(len=6) :: datatype
30  integer :: numvar
31  integer :: xlat
32  integer :: xlon
33  integer :: xtime
34  integer :: datelen
35  integer :: i_mask
36  integer :: i_sst
37  integer :: i_ice
38  integer :: i_sfcT
39  integer :: i_iceT
40  integer :: i_sfcTl
41  integer :: i_zorl
42  integer :: i_hice
43  character(len=20), allocatable :: varnames(:)
44  character(len=20), allocatable :: latname
45  character(len=20), allocatable :: lonname
46  character(len=20), allocatable :: dimnameEW
47  character(len=20), allocatable :: dimnameNS
48  character(len=20), allocatable :: dimnameTIME
49  character(len=20), allocatable :: dimnameDATE
50  character(len=1), allocatable :: times(:,:)
51 
52  real(r_kind), allocatable :: nwp_mask_c(:,:)
53  real(r_kind), allocatable :: nwp_sst_c(:,:,:)
54  real(r_kind), allocatable :: nwp_ice_c(:,:,:)
55  real(r_kind), allocatable :: nwp_sfct_c(:,:,:)
56  real(r_kind), allocatable :: nwp_icet_c(:,:,:)
57  real(r_kind), allocatable :: nwp_zorl_c(:,:,:)
58  real(r_kind), allocatable :: nwp_hice_c(:,:,:)
59 
60  real(r_kind), allocatable :: nwp_mask_w(:,:)
61  real(r_kind), allocatable :: nwp_sst_w(:,:)
62  real(r_kind), allocatable :: nwp_ice_w(:,:)
63  real(r_kind), allocatable :: nwp_sfct_w(:,:)
64  real(r_kind), allocatable :: nwp_icet_w(:,:)
65  real(r_kind), allocatable :: nwp_sfctl_w(:,:)
66  real(r_kind), allocatable :: nwp_zorl_w(:,:)
67  real(r_kind), allocatable :: nwp_hice_w(:,:)
68 
69  end type nwp_type
70 
71  type, extends(nwp_type) :: fcst_nwp
72  ! The pointers are carryover from when I inherited the code from
73  ! GSL's work with HRRR for a similar use. I am not sure with
74  ! object based coding in Fortran if it needs to have parts
75  ! initialized to gain access to the procedures within it. - D. Wright.
76  type(nwpbase), pointer :: head => NULL()
77  type(nwpbase), pointer :: tail => NULL()
78  contains
79  procedure :: initial => initial_nwp
80  procedure :: list_initial => list_initial_nwp
81  procedure :: read_n => read_nwp
82  procedure :: get_time_ind => get_time_ind_nwp
83  procedure :: finish => finish_nwp
84  end type fcst_nwp
85 
86  type(ncio) :: ncdata
87 ! type(map_util) :: map
88 
89  contains
90 
99  subroutine initial_nwp(this,itype,wcstart)
100  class(fcst_nwp) :: this
101 
102  character(len=6), intent(in) :: itype
103  character(len=4), intent(in) :: wcstart
104 
105 ! FVCOM grid
106  if (itype==' FVCOM') then
107  this%datatype = itype
108  this%numvar = 5
109 
110  this%i_mask = 1
111  this%i_sst = 2
112  this%i_ice = 3
113  this%i_iceT = 4
114  this%i_hice = 5
115  this%i_sfcT = 0
116  this%i_zorl = 0
117 
118  allocate(this%varnames(this%numvar))
119  this%varnames(1) = 'glmask'
120  this%varnames(2) = 'tsfc'
121  this%varnames(3) = 'aice'
122  this%varnames(4) = 'tisfc'
123  this%varnames(5) = 'vice'
124 
125  allocate(this%latname)
126  allocate(this%lonname)
127  this%latname = 'lat'
128  this%lonname = 'lon'
129 
130  allocate(this%dimnameEW)
131  allocate(this%dimnameNS)
132  allocate(this%dimnameTIME)
133  allocate(this%dimnameDATE)
134  this%dimnameEW = 'lon'
135  this%dimnameNS = 'lat'
136  this%dimnameTIME = 'Time'
137  this%dimnameDATE = 'DateStrLen'
138 
139 ! FV3LAM grid
140 
141  else if (trim(itype)=='FV3LAM' .AND. wcstart=='warm') then
142  this%datatype = itype
143  this%numvar = 8
144 
145  this%i_mask = 1
146  this%i_sst = 2
147  this%i_ice = 3
148  this%i_iceT = 4
149  this%i_sfcT = 5
150  this%i_sfcTl= 6
151  this%i_zorl = 7
152  this%i_hice = 8
153 
154  allocate(this%varnames(this%numvar))
155  this%varnames(1) = 'slmsk'
156  this%varnames(2) = 'tsea'
157  this%varnames(3) = 'fice'
158  this%varnames(4) = 'tisfc'
159  this%varnames(5) = 'tsfc'
160  this%varnames(6) = 'tsfcl'
161  this%varnames(7) = 'zorli'
162  this%varnames(8) = 'hice'
163 
164  allocate(this%latname)
165  allocate(this%lonname)
166  this%latname = 'yaxis_1'
167  this%lonname = 'xaxis_1'
168 
169  allocate(this%dimnameEW)
170  allocate(this%dimnameNS)
171  allocate(this%dimnameTIME)
172  this%dimnameEW = 'xaxis_1'
173  this%dimnameNS = 'yaxis_1'
174  this%dimnameTIME = 'Time'
175 
176  else if (trim(itype)=='FV3LAM' .AND. wcstart=='cold') then
177  this%datatype = itype
178  this%numvar = 6
179 
180  this%i_mask = 1
181  this%i_sst = 2
182  this%i_ice = 3
183  this%i_iceT = 4
184  this%i_zorl = 5
185  this%i_hice = 6
186  this%i_sfcT = 0
187 
188  allocate(this%varnames(this%numvar))
189  this%varnames(1) = 'slmsk'
190  this%varnames(2) = 'tsea'
191  this%varnames(3) = 'fice'
192  this%varnames(4) = 'tisfc'
193  this%varnames(5) = 'zorl'
194  this%varnames(6) = 'hice'
195 
196  allocate(this%latname)
197  allocate(this%lonname)
198  this%latname = 'yaxis_1'
199  this%lonname = 'xaxis_1'
200 
201  allocate(this%dimnameEW)
202  allocate(this%dimnameNS)
203  allocate(this%dimnameTIME)
204  this%dimnameEW = 'xaxis_1'
205  this%dimnameNS = 'yaxis_1'
206  this%dimnameTIME = 'Time'
207 
208 ! If the data type does not match one of the known types, exit.
209 
210  else
211  write(6,*) 'Unknown data type:', itype
212  stop 1234
213  end if
214 
215  this%head => null()
216  this%tail => null()
217 
218  write(6,*) 'Finished initial_nwp'
219  write(6,*) ' '
220 
221  end subroutine initial_nwp
222 
228  subroutine list_initial_nwp(this)
229 
230  class(fcst_nwp) :: this
231 
232  integer :: k
233 
234  write(6,*) 'List initial setup for ', this%datatype
235  write(6,*) 'number of variables ', this%numvar
236  write(6,*) 'variable index: mask, sst, ice, sfcT, sfcTl'
237  write(6,'(15x,10I3)') this%i_mask, this%i_sst, this%i_ice, &
238  & this%i_sfcT, this%i_sfcTl
239  write(6,*) 'variable name:'
240  do k=1,this%numvar
241  write(6,*) k,trim(this%varnames(k))
242  enddo
243 
244  write(6,*) 'Finished list_initial_nwp'
245  write(6,*) ' '
246 
247  end subroutine list_initial_nwp
248 
272  subroutine read_nwp(this,filename,itype,wcstart,numlon,numlat,numtimes,time_to_get,mask,sst,ice,sfcT,iceT,sfcTl,zorl,hice,ybegin,yend)
273 
274  class(fcst_nwp) :: this
275 
276  character(len=6), intent(in) :: itype
277  character(len=*), intent(in) :: filename
278  character(len=4), intent(in) :: wcstart
279 
280  integer, intent(in) :: time_to_get
281  integer, intent(in) :: ybegin,yend
282  integer, intent(inout) :: numlon, numlat, numtimes
283 ! real(r_single), intent(inout) :: mask(:,:), sst(:,:), ice(:,:), sfcT(:,:)
284  real(r_kind), intent(inout) :: mask(:,:),sst(:,:),ice(:,:),sfct(:,:) &
285  ,icet(:,:),sfctl(:,:),zorl(:,:),hice(:,:)
286 
287 !
288 ! Open the file using module_ncio.f90 code, and find the number of
289 ! lat/lon points
290 
291  call ncdata%open(trim(filename),'r',200)
292  call ncdata%get_dim(this%dimnameEW,this%xlon)
293  call ncdata%get_dim(this%dimnameNS,this%xlat)
294  call ncdata%get_dim(this%dimnameTIME,this%xtime)
295 
296  write(6,*) 'number of longitudes for file ', filename, this%xlon
297  numlon = this%xlon
298  write(6,*) 'number of latitudes for file ', filename, this%xlat
299  !numlat = this%xlat
300  numlat = yend-ybegin+1
301  write(6,*) 'number of times for file ', filename, this%xtime
302  numtimes = this%xtime
303  write(6,*) 'the range of Y for this domain is=',ybegin,yend
304 
305 ! Allocate all the arrays to receive data
306  if (wcstart == 'cold' .OR. itype == ' FVCOM') then
307  allocate(this%nwp_mask_c(this%xlon,this%xlat))
308  allocate(this%nwp_sst_c(this%xlon,this%xlat,this%xtime))
309  allocate(this%nwp_ice_c(this%xlon,this%xlat,this%xtime))
310  allocate(this%nwp_sfcT_c(this%xlon,this%xlat,this%xtime))
311  allocate(this%nwp_iceT_c(this%xlon,this%xlat,this%xtime))
312  allocate(this%nwp_zorl_c(this%xlon,this%xlat,this%xtime))
313  allocate(this%nwp_hice_c(this%xlon,this%xlat,this%xtime))
314 
315 ! Get variables from the data file, but only if the variable is
316 ! defined for that data type.
317 
318  write(6,*) 'itype = ', itype
319  write(6,*) 'wcstart = ', wcstart
320  write(6,*) 'xlat = ', this%xlat
321  write(6,*) 'xlon = ', this%xlon
322  write(6,*) 'xtime = ', this%xtime
323 
324  if (this%i_mask .gt. 0) then
325  call ncdata%get_var(this%varnames(this%i_mask),this%xlon, &
326  this%xlat,this%nwp_mask_c)
327  mask = this%nwp_mask_c(:,ybegin:yend)
328  end if
329  if (this%i_sst .gt. 0) then
330  write(6,*) 'get sst for cold or FVCOM'
331  call ncdata%get_var(this%varnames(this%i_sst),this%xlon, &
332  this%xlat,this%xtime,this%nwp_sst_c)
333  sst = this%nwp_sst_c(:,ybegin:yend,time_to_get)
334  end if
335  if (this%i_ice .gt. 0) then
336  call ncdata%get_var(this%varnames(this%i_ice),this%xlon, &
337  this%xlat,this%xtime,this%nwp_ice_c)
338  ice = this%nwp_ice_c(:,ybegin:yend,time_to_get)
339  end if
340  if (this%i_sfcT .gt. 0) then
341  call ncdata%get_var(this%varnames(this%i_sfcT),this%xlon, &
342  this%xlat,this%xtime,this%nwp_sfcT_c)
343  sfct = this%nwp_sfcT_c(:,ybegin:yend,time_to_get)
344  end if
345  if (this%i_iceT .gt. 0) then
346  call ncdata%get_var(this%varnames(this%i_iceT),this%xlon, &
347  this%xlat,this%xtime,this%nwp_iceT_c)
348  icet = this%nwp_iceT_c(:,ybegin:yend,time_to_get)
349  end if
350  if (this%i_zorl .gt. 0) then
351  call ncdata%get_var(this%varnames(this%i_zorl),this%xlon, &
352  this%xlat,this%xtime,this%nwp_zorl_c)
353  zorl = this%nwp_zorl_c(:,ybegin:yend,time_to_get)
354  end if
355  if (this%i_hice .gt. 0) then
356  call ncdata%get_var(this%varnames(this%i_hice),this%xlon, &
357  this%xlat,this%xtime,this%nwp_hice_c)
358  hice = this%nwp_hice_c(:,ybegin:yend,time_to_get)
359  end if
360 
361  else if (wcstart == 'warm') then
362  allocate(this%nwp_mask_w(this%xlon,this%xlat))
363  allocate(this%nwp_sst_w(this%xlon,this%xlat))
364  allocate(this%nwp_ice_w(this%xlon,this%xlat))
365  allocate(this%nwp_sfcT_w(this%xlon,this%xlat))
366  allocate(this%nwp_iceT_w(this%xlon,this%xlat))
367  allocate(this%nwp_sfcTl_w(this%xlon,this%xlat))
368  allocate(this%nwp_zorl_w(this%xlon,this%xlat))
369  allocate(this%nwp_hice_w(this%xlon,this%xlat))
370 ! Get variables from the data file, but only if the variable is
371 ! defined for that data type.
372 
373  write(6,*) 'itype = ', itype
374  write(6,*) 'wcstart =', wcstart
375  write(6,*) 'xlat = ', this%xlat
376  write(6,*) 'xlon = ', this%xlon
377  write(6,*) 'xtime = ', this%xtime
378 
379  if (this%i_mask .gt. 0) then
380  call ncdata%get_var(this%varnames(this%i_mask),this%xlon, &
381  this%xlat,this%nwp_mask_w)
382  mask = this%nwp_mask_w(:,ybegin:yend)
383  end if
384  if (this%i_sst .gt. 0) then
385  call ncdata%get_var(this%varnames(this%i_sst),this%xlon, &
386  this%xlat,this%nwp_sst_w)
387  sst = this%nwp_sst_w(:,ybegin:yend)
388  end if
389  if (this%i_ice .gt. 0) then
390  call ncdata%get_var(this%varnames(this%i_ice),this%xlon, &
391  this%xlat,this%nwp_ice_w)
392  ice = this%nwp_ice_w(:,ybegin:yend)
393  end if
394  if (this%i_sfcT .gt. 0) then
395  call ncdata%get_var(this%varnames(this%i_sfcT),this%xlon, &
396  this%xlat,this%nwp_sfcT_w)
397  sfct = this%nwp_sfcT_w(:,ybegin:yend)
398  end if
399  if (this%i_iceT .gt. 0) then
400  call ncdata%get_var(this%varnames(this%i_iceT),this%xlon, &
401  this%xlat,this%nwp_iceT_w)
402  icet = this%nwp_iceT_w(:,ybegin:yend)
403  end if
404  if (this%i_sfcTl .gt. 0) then
405  call ncdata%get_var(this%varnames(this%i_sfcTl),this%xlon, &
406  this%xlat,this%nwp_sfcTl_w)
407  sfctl = this%nwp_sfcTl_w(:,ybegin:yend)
408  end if
409  if (this%i_zorl .gt. 0) then
410  call ncdata%get_var(this%varnames(this%i_zorl),this%xlon, &
411  this%xlat,this%nwp_zorl_w)
412  zorl = this%nwp_zorl_w(:,ybegin:yend)
413  end if
414  if (this%i_hice .gt. 0) then
415  call ncdata%get_var(this%varnames(this%i_hice),this%xlon, &
416  this%xlat,this%nwp_hice_w)
417  hice = this%nwp_hice_w(:,ybegin:yend)
418  end if
419 
420  else
421  write(6,*) 'Choose either "warm" or "cold" for file'
422  stop 'Error in wcstart. Check spelling or if variable was assigned'
423  end if
424 ! Close the netCDF file.
425 
426  call ncdata%close
427 
428  write(6,*) 'Finished read_nwp'
429  write(6,*) ' '
430 
431  end subroutine read_nwp
432 
439  subroutine finish_nwp(this,itype,wcstart)
440 
441  class(fcst_nwp) :: this
442  character(len=6), intent(in) :: itype
443  character(len=4), intent(in) :: wcstart
444 
445  type(nwpbase), pointer :: thisobs,thisobsnext
446 
447  deallocate(this%varnames)
448  deallocate(this%latname)
449  deallocate(this%lonname)
450  deallocate(this%dimnameEW)
451  deallocate(this%dimnameNS)
452  deallocate(this%dimnameTIME)
453  if (wcstart == 'cold' .OR. itype==' FVCOM') then
454  deallocate(this%nwp_mask_c)
455  deallocate(this%nwp_sst_c)
456  deallocate(this%nwp_ice_c)
457  deallocate(this%nwp_sfcT_c)
458  deallocate(this%nwp_iceT_c)
459  deallocate(this%nwp_zorl_c)
460  deallocate(this%nwp_hice_c)
461  if (itype==' FVCOM') deallocate(this%dimnameDATE)
462  else if (wcstart == 'warm') then
463  deallocate(this%nwp_mask_w)
464  deallocate(this%nwp_sst_w)
465  deallocate(this%nwp_ice_w)
466  deallocate(this%nwp_sfcT_w)
467  deallocate(this%nwp_iceT_w)
468  deallocate(this%nwp_sfcTl_w)
469  deallocate(this%nwp_zorl_w)
470  deallocate(this%nwp_hice_w)
471  else
472  write(6,*) 'no deallocation'
473  end if
474 
475  thisobs => this%head
476  if(.NOT.associated(thisobs)) then
477  write(6,*) 'No memory to release'
478  return
479  endif
480  do while(associated(thisobs))
481 
482  thisobsnext => thisobs%next
483  call thisobs%destroy()
484  thisobs => thisobsnext
485  enddo
486 
487  write(6,*) 'Finished finish_nwp'
488  write(6,*) ' '
489 
490  end subroutine finish_nwp
491 
501  subroutine get_time_ind_nwp(this,filename,instr,outindex)
502 
503  class(fcst_nwp) :: this
504 
505  character(len=*), intent(in) :: filename
506  character(len=*), intent(in) :: instr
507  integer, intent(out) :: outindex
508 
509  character(len=26) :: temp
510  integer :: foundind
511  integer :: k,i
512 
513 ! Open the file using module_ncio.f90 code, and find the length of
514 ! time in the file
515  call ncdata%open(trim(filename),'r',200)
516  call ncdata%get_dim(this%dimnameTIME,this%xtime)
517  call ncdata%get_dim(this%dimnameDATE,this%datelen)
518  write(6,*) 'xtime = ', this%xtime
519  write(6,*) 'datelen = ', this%datelen
520  allocate(this%times(this%datelen,this%xtime))
521  call ncdata%get_var('Times',this%datelen,this%xtime,this%times)
522 
523  foundind = 0
524 
525  do k=1,this%xtime,1
526  do i = 1,len(temp),1
527  temp(i:i) = this%times(i,k)
528  end do
529  if (trim(temp) == trim(instr)) then !If times are equal return k
530  outindex = k
531  foundind = 1
532  end if
533  end do
534  if (foundind == 0) then
535  outindex = -999
536  deallocate(this%times)
537  call ncdata%close
538  write(6,*) 'WARNING: Supplied time not found in file: ', trim(instr)
539  write(6,*) 'Stoppping fvcom_to_FV3 and proceeding without using FVCOM data'
540  stop
541  end if
542 
543  deallocate(this%times)
544  call ncdata%close
545 
546  end subroutine get_time_ind_nwp
547 
548 end module module_nwp
Module to hold specification kinds for variable declaration.
Definition: kinds.f90:11
This module defines nwp observation data structure and the method to read and write observations from...
Functions to read and write netcdf files.
Definition: module_ncio.f90:7
subroutine get_time_ind_nwp(this, filename, instr, outindex)
This subroutine searches the FVCOM 'Times' variable and returns the matching index.
Definition: module_nwp.f90:501
procedure read_n=> read_nwp
Initialize arrays, get data.
Definition: module_nwp.f90:81
subroutine read_nwp(this, filename, itype, wcstart, numlon, numlat, numtimes, time_to_get, mask, sst, ice, sfcT, iceT, sfcTl, zorl, hice, ybegin, yend)
This subroutine initializes arrays to receive the NWP data, and opens the file and gets the data...
Definition: module_nwp.f90:272
subroutine initial_nwp(this, itype, wcstart)
This subroutine defines the number of variables and their names for each NWP data type...
Definition: module_nwp.f90:99
procedure finish=> finish_nwp
Finish and deallocate.
Definition: module_nwp.f90:83
This module defines FV3LAM and FVCOM forecast data structure and the method to read and write observa...
Definition: module_nwp.f90:15
subroutine list_initial_nwp(this)
This subroutine lists the setup for NWP data that was done by the initial_nwp subroutine.
Definition: module_nwp.f90:228
procedure get_time_ind=> get_time_ind_nwp
Get time ind.
Definition: module_nwp.f90:82
subroutine finish_nwp(this, itype, wcstart)
Finish and deallocate.
Definition: module_nwp.f90:439
procedure initial=> initial_nwp
Defines vars and names.
Definition: module_nwp.f90:79
procedure list_initial=> list_initial_nwp
List the setup.
Definition: module_nwp.f90:80