My Project
mod_nesting.f90
Go to the documentation of this file.
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 !/===========================================================================/
13 ! Copyright (c) 2007, The University of Massachusetts Dartmouth
14 ! Produced at the School of Marine Science & Technology
15 ! Marine Ecosystem Dynamics Modeling group
16 ! All rights reserved.
17 !
18 ! FVCOM has been developed by the joint UMASSD-WHOI research team. For
19 ! details of authorship and attribution of credit please see the FVCOM
20 ! technical manual or contact the MEDM group.
21 !
22 !
23 ! This file is part of FVCOM. For details, see http://fvcom.smast.umassd.edu
24 ! The full copyright notice is contained in the file COPYRIGHT located in the
25 ! root directory of the FVCOM code. This original header must be maintained
26 ! in all distributed versions.
27 !
28 ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
30 ! THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 ! PURPOSE ARE DISCLAIMED.
32 !
33 !/---------------------------------------------------------------------------/
34 ! CVS VERSION INFORMATION
35 ! $Id$
36 ! $Name$
37 ! $Revision$
38 !/===========================================================================/
39 
41  use all_vars
42  use mod_utils
43  use mod_ncdio
44  use mod_par
45  use sinter
46  implicit none
47 
48  SAVE
49 
50  ! For data IO
51  TYPE nest_data
52  INTEGER :: idx =0
53  INTEGER :: rng(2) =0
54  INTEGER :: nblk=0
55 
56  REAL(sp), POINTER :: ua_blk(:,:),va_blk(:,:),el_blk(:,:)
57  REAL(sp), POINTER :: u_blk(:,:,:),v_blk(:,:,:)
58  REAL(sp), POINTER :: s1_blk(:,:,:),t1_blk(:,:,:)
59  REAL(sp), POINTER :: hyw_blk(:,:,:)
60  TYPE(time), POINTER :: time_blk(:)
61 
62  REAL(sp), POINTER :: wcell_blk(:,:),wnode_blk(:,:)
63 
64  END TYPE nest_data
65 
66 
67 
68  ! GRID AND DATA FOR RUNNING AS SUBDOMAIN
69  TYPE(grid), POINTER :: nesting_grid
70  TYPE(nest_data), POINTER :: nesting_data
71  TYPE(ncfile), POINTER :: nesting_file
72 
73 
74  !========================================================
75  ! Used in NESTING CODE
76  ! This memory holds the data for each variable at the current time.
77  ! This is where the data that is updated is stored in arrays which
78  ! are the size of the nesting boundary, and indexed to the FVCOM domain.
79  REAL(sp), ALLOCATABLE :: ua_nest(:),va_nest(:),el_nest(:)
80  REAL(sp), ALLOCATABLE :: u_nest(:,:),v_nest(:,:)
81  REAL(sp), ALLOCATABLE :: s1_nest(:,:),t1_nest(:,:)
82  REAL(sp), ALLOCATABLE :: hyw_nest(:,:)
83 
84  REAL(sp), ALLOCATABLE :: u_nest_l(:,:),v_nest_l(:,:)
85  REAL(sp), ALLOCATABLE :: s1_nest_l(:,:),t1_nest_l(:,:)
86  REAL(sp), ALLOCATABLE :: hyw_nest_l(:,:)
87 
88  REAL(sp), ALLOCATABLE, TARGET :: zz_l(:,:),zz1_l(:,:),h_l(:),h1_l(:)
89 
90  REAL(sp), ALLOCATABLE :: wcell_nest(:),wnode_nest(:)
91 
92  !
93  TYPE(ncvar), POINTER :: var_ua
94  TYPE(ncvar), POINTER :: var_va
95  TYPE(ncvar), POINTER :: var_el
96  TYPE(ncvar), POINTER :: var_u
97  TYPE(ncvar), POINTER :: var_v
98  TYPE(ncvar), POINTER :: var_s1
99  TYPE(ncvar), POINTER :: var_t1
100  TYPE(ncvar), POINTER :: var_hyw
101  TYPE(ncvar), POINTER :: var_time1
102  TYPE(ncvar), POINTER :: var_time2
103 
104  TYPE(ncvar), POINTER :: var_wcell
105  TYPE(ncvar), POINTER :: var_wnode
106 
107  !========================================================
108 
109 
110  ! GRID AND DATA FOR OUTPUT
111  INTEGER :: ncnest_num
112  CHARACTER(LEN=80), ALLOCATABLE :: ncnest_fnames(:)
113  TYPE(grid), POINTER :: ncnest_grids(:)
114  TYPE(nest_data), POINTER :: ncnest_data(:)
115 
116 
117  LOGICAL, PRIVATE :: need_init_nest = .true.
118 
120 
121  !--Parameters in NameList NML_NESTING
122  !TYPE OF NESTING:
123  ! 1: DIRECT NESTING -- The input is the direct NCNEST output of
124  ! large domain FVCOM model
125  ! 2: INDIRECT NESTING -- Same as 1, but the input file is the subtidal
126  ! values from the NCNEST output of large domain
127  ! FVCOM model plus the Forman tidal analysis
128  ! elevations and velocities
129  ! 3: RELAXATION NESTING -- The nesting with a relaxation method (an example
130  ! is to get nesting data from HYCOM)
131  LOGICAL nesting_on !!TRUE IF OUTPUT RESART FILES
132  CHARACTER(LEN=80) nesting_type !!TYPE OF NESTING: 1, 2, 3
133  INTEGER :: nesting_blocksize !!SIZE OF DATA BLOCKS IN FILE
134  CHARACTER(LEN=80) nesting_file_name !!NAME OF RESTART FILE
135 
136  namelist /nml_nesting/ &
137  & nesting_on, &
138  & nesting_type, &
139  & nesting_blocksize, &
141 
142 
143  !--Parameters in NameList NML_NCNEST
144  LOGICAL ncnest_on
145  INTEGER :: ncnest_blocksize
146  CHARACTER(LEN=160) ncnest_node_files
147  CHARACTER(LEN=80) ncnest_out_interval
148 
149  namelist /nml_ncnest/ &
150  & ncnest_on, &
151  & ncnest_blocksize, &
152  & ncnest_node_files, &
154 
155 
156  INTEGER :: kb_l
157  INTEGER :: kbm1_l
158 
159 CONTAINS
160  !==============================================================================!
161  !
162  !==============================================================================!
163  SUBROUTINE name_list_initialize_nest
165 
166  IMPLICIT NONE
167 
168  !--Parameters in NameList NML_NESTING
169  nesting_on = .false.
170  nesting_type = "'1' or '2' or '3'"
171  nesting_blocksize = -1
172  nesting_file_name = trim(casename)//"_nesting.nc"
173 
174  !--Parameters in NameList NML_NCNEST
175  ncnest_on = .false.
176  ncnest_blocksize = -1
177  ncnest_node_files = "none"
178  ncnest_out_interval = "A length of time: 'seconds= ','days= ', or 'cycles= '"
179 
180 
181  kb_l = 0
182  kbm1_l = 0
183 
184  RETURN
185  END SUBROUTINE name_list_initialize_nest
186  !==============================================================================!
187  !
188  !==============================================================================!
189  SUBROUTINE name_list_print_nest
191 
192  IMPLICIT NONE
193 
194  WRITE(unit=ipt,nml=nml_ncnest)
195 
196  WRITE(unit=ipt,nml=nml_nesting)
197 
198 
199  RETURN
200  END SUBROUTINE name_list_print_nest
201  !==============================================================================!
202  !
203  !==============================================================================!
204  SUBROUTINE name_list_read_nest
206  USE control
208 
209  IMPLICIT NONE
210 
211  INTEGER :: ios,I
212  CHARACTER(LEN=120) :: FNAME
213 
214  IF(dbg_set(dbg_sbr)) write(ipt,*) "Subroutine Begins: name_list_read_nest;"
215 
216  ios = 0
217  fname = "./"//trim(casename)//"_run.nml"
218  IF(dbg_set(dbg_io)) write(ipt,*) "Get_nestpar: File: ",trim(fname)
219 
220  CALL fopen(nmlunit,trim(fname),'cfr')
221 
222  !READ NAME LIST FILE
223 
224  !READ NESTING FLAG
225  READ(unit=nmlunit, nml=nml_nesting,iostat=ios)
226  IF(ios /= 0)THEN
227  IF(dbg_set(dbg_log)) write(unit=ipt,nml=nml_nesting)
228  CALL fatal_error("Can Not Read NameList NML_NESTING from file: "//trim(fname))
229  END IF
230 
231  if(dbg_set(dbg_scl)) &
232  & write(ipt,*) "Read_Name_List:NML_NESTING"
233 
234  if(dbg_set(dbg_scl)) &
235  & write(unit=ipt,nml=nml_nesting)
236 
237  rewind(nmlunit)
238 
239  !READ NESTING FLAG
240  READ(unit=nmlunit, nml=nml_ncnest,iostat=ios)
241  IF(ios /= 0)THEN
242  IF(dbg_set(dbg_log)) write(unit=ipt,nml=nml_ncnest)
243  CALL fatal_error("Can Not Read NameList NML_NCNEST from file: "//trim(fname))
244  END IF
245 
246  if(dbg_set(dbg_scl)) &
247  & write(ipt,*) "Read_Name_List: NML_NCNEST"
248 
249  if(dbg_set(dbg_scl)) &
250  & write(unit=ipt,nml=nml_ncnest)
251 
252 
253 
254  CLOSE(nmlunit)
255 
256  ! DO SOME BASIC CHECKING ON THE NESTING NAMELIST
257  IF(nesting_on) THEN
258 
259  IF( nesting_blocksize < 2) CALL fatal_error &
260  & ("THE NESTING_BLOCKSIZE IS LESS THAN TWO IN THE NESTING NAME LIST")
261 
262  IF(len_trim(nesting_file_name) == 0 ) CALL fatal_error &
263  & ("THE NESTING FILE NAME IS EMPTY IN THE NAME LIST")
264 
265  END IF
266 
267  IF(ncnest_on) THEN
268 
269  IF( ncnest_blocksize < 2) CALL fatal_error &
270  & ("THE NCNEST_BLOCKSIZE IS LESS THAN TWO IN THE NCNEST NAME LIST")
271 
272  IF(ncnest_node_files == 'none' .or. len_trim(ncnest_node_files)==0)CALL fatal_error &
273  & ("THE NCNEST_NODE_FILES VARIABLE IS EMPTY IN THE NCNEST NAME LIST")
274 
276 
277  END IF
278 
279  CLOSE(nmlunit)
280 
281  if(dbg_set(dbg_sbr)) &
282  & write(ipt,*) "Subroutine Ends: name_list_read_nest;"
283 
284  END SUBROUTINE name_list_read_nest
285 
286  SUBROUTINE open_nesting_file
287  IMPLICIT NONE
288  TYPE(ncfile), POINTER :: NCF
289  integer :: charnum
290  logical :: back=.true.
291  character(len=160) :: pathnfile
292  ! LOAD NESTING NETCDF FILE
293  IF (nesting_on) THEN
294 
295  ! TEST FILE NAME
296  charnum = index(nesting_file_name,".nc",back)
297  if (charnum /= len_trim(nesting_file_name)-2)&
298  & CALL warning("Nesting File does not end in .nc", &
299  & trim(nesting_file_name))
300 
301  ! INITIALIZE TYPE TO HOLD FILE METADATA
302  pathnfile= trim(input_dir)//trim(nesting_file_name)
303  CALL nc_init(ncf,pathnfile)
304 
305  ! OPEN THE FILE AND LOAD METADATA
306  if(.not. ncf%OPEN) then
307  Call nc_open(ncf)
308  CALL nc_load(ncf)
309  filehead => add(filehead,ncf)
310  end if
311 
312  END IF
313 
314  END SUBROUTINE open_nesting_file
315 
316 
317 
318  ! DEFINE SOME DUMMY ROUTINES
319 
320  SUBROUTINE set_var(NOW,UA,VA,EL,U,V,S1,T1,HYW)
321  IMPLICIT NONE
322  TYPE(time), INTENT(IN) :: NOW
323  REAL(SP), ALLOCATABLE, OPTIONAL :: UA(:),VA(:),EL(:)
324  REAL(SP), ALLOCATABLE, OPTIONAL :: U(:,:),V(:,:),S1(:,:),T1(:,:),HYW(:,:)
325  END SUBROUTINE set_var
326 
327  SUBROUTINE set_var_wave(NOW,HSC1,TPEAK,DIRDEG1)
328  IMPLICIT NONE
329  TYPE(time), INTENT(IN) :: NOW
330  REAL(SP), ALLOCATABLE, OPTIONAL :: HSC1(:),TPEAK(:),DIRDEG1(:)
331  END SUBROUTINE set_var_wave
332 
333  SUBROUTINE archive_nest
334  IMPLICIT NONE
335  END SUBROUTINE archive_nest
336 
337  SUBROUTINE archive_nest_wave
338  IMPLICIT NONE
339  END SUBROUTINE archive_nest_wave
340 
341 
342 !====================================================================
343  SUBROUTINE update_itime_nest(VAR1,VAR2,NOW)
344  IMPLICIT NONE
345  TYPE(ncvar), POINTER :: VAR1
346  TYPE(ncvar), POINTER :: VAR2
347  TYPE(ncatt), POINTER :: ATT
348  TYPE(time), INTENT(in) :: NOW
349  INTEGER, POINTER :: D1,D2
350  LOGICAL :: TEST2
351  INTEGER :: TEST
352  CHARACTER(len=80):: TZONE
353 
354  test2 = is_valid_itime(var1,var2,tzone)
355  IF(.not. test2) THEN
356  CALL print_var(var1)
357  CALL print_var(var2)
358  CALL fatal_error &
359  ("CAN NOT UPDATE TIME FOR INVALID INTEGER TIME VARIABLES")
360  END IF
361 
362  CALL nc_point_var(var1,d1)
363 
364  CALL nc_point_var(var2,d2)
365 
366  test = time2ncitime_nest(now,d1,d2)
367 
368 ! if(.not. TEST) call fatal_error("That is bad times man!")
369  if(test==0) call fatal_error("That is bad times man!")
370  ! THIS SHOULD NEVER HAPPEN?
371 
372  END SUBROUTINE update_itime_nest
373 !====================================================================
374 !======================================================
375  FUNCTION time2ncitime_nest(MJD,D,MS) RESULT(res)
376  implicit none
377  INTEGER :: res
378  TYPE(time), INTENT(IN) :: mjd
379  INTEGER, INTENT(OUT) :: d, ms
380  REAL(dp) :: msec
381 
382  res = -1
383  msec = dble(mjd%MuSod) / 1000.0_dp
384  ms = anint(msec)
385 
386  ! CHECK TO MAKE SURE IT IS NOT TOO LARGE
387  IF (abs(mjd%MJD) .GT. huge(d)) THEN
388  res =0
389  return
390  END IF
391 
392  d = mjd%MJD
393 
394  END FUNCTION time2ncitime_nest
395 !======================================================
396 !====================================================================
397  SUBROUTINE update_float_time_nest(VAR,NOW)
398  IMPLICIT NONE
399  TYPE(ncvar), POINTER :: VAR
400  TYPE(time), INTENT(in) :: NOW
401  REAL(SP), POINTER :: Data
402  LOGICAL :: TEST
403  CHARACTER(len=80):: TZONE
404 
405  test = is_valid_float_days(var,tzone)
406  IF(.not. test) THEN
407  CALL print_var(var)
408  call print_att_list(var)
409  CALL fatal_error &
410  ("CAN NOT UPDATE TIME FOR INVALID FLOATING POINT TIME VARIABLE")
411  END IF
412 
413  CALL nc_point_var(var,data)
414 
415  Data = days(now)
416 
417  END SUBROUTINE update_float_time_nest
418 !====================================================================
419 !====================================================================
420  FUNCTION float_time_object_nest(use_mjd,DIM,size) RESULT(VAR)
421  IMPLICIT NONE
422  TYPE(ncvar), POINTER :: var
423  logical, intent(in) :: use_mjd
424  TYPE(ncdim), POINTER, OPTIONAL :: dim
425  INTEGER, OPTIONAL :: size
426  TYPE(ncatt), POINTER :: att
427  REAL(sp),pointer :: data_vec(:)
428  REAL(sp),pointer :: data_scl
429 
430  IF(PRESENT(size)) THEN
431  ALLOCATE(data_vec(size))
432  ELSE
433  ALLOCATE(data_vec(1))
434  data_scl =>data_vec(1)
435  END IF
436 
437  IF (PRESENT(dim)) THEN
438  var => nc_make_pvar(name='time', values=data_vec, dim1= dim)
439  if(associated(var%vec_flt))then
440  var%scl_flt => var%vec_flt(1)
441  else
442  var%scl_dbl => var%vec_dbl(1)
443  endif
444  ELSE
445  var => nc_make_pvar(name='time', values=data_scl)
446  END IF
447 
448  att => nc_make_att(name='long_name',values='time')
449  var => add(var,att)
450 
451  IF (use_mjd) THEN
452  att => nc_make_att(name='units',values=mjd_units)
453  var => add(var,att)
454 
455  att => nc_make_att(name='format',values=fmat)
456  var => add(var,att)
457 
458  att => nc_make_att(name='time_zone',values='UTC')
459  var => add(var,att)
460 
461  ELSE
462  att => nc_make_att(name='units',values=days_units)
463  var => add(var,att)
464 
465  att => nc_make_att(name='time_zone',values='none')
466  var => add(var,att)
467  END IF
468 
469 
470  END FUNCTION float_time_object_nest
471 !====================================================================
472 !====================================================================
473  FUNCTION itime_object_nest(use_mjd,DIM,size) RESULT(VAR)
474  IMPLICIT NONE
475  TYPE(ncvar), POINTER :: var
476  logical, intent(in) :: use_mjd
477  TYPE(ncdim), POINTER, OPTIONAL :: dim
478  INTEGER, OPTIONAL :: size
479  TYPE(ncatt), POINTER :: att
480  INTEGER,POINTER :: data_vec(:)
481  INTEGER,POINTER :: data_scl
482 
483  IF(PRESENT(size)) THEN
484  ALLOCATE(data_vec(size))
485  ELSE
486  ALLOCATE(data_vec(1))
487  data_scl =>data_vec(1)
488  END IF
489 
490  ! Itime
491  IF (PRESENT(dim)) THEN
492  var => nc_make_pvar(name='Itime', values=data_vec, dim1= dim)
493  var%SCL_INT => var%VEC_INT(1)
494  ELSE
495  var => nc_make_pvar(name='Itime', values=data_scl)
496  END IF
497 
498  IF (use_mjd) THEN
499  att => nc_make_att(name='units',values=mjd_units)
500  var => add(var,att)
501 
502  att => nc_make_att(name='format',values=fmat)
503  var => add(var,att)
504 
505  att => nc_make_att(name='time_zone',values='UTC')
506  var => add(var,att)
507  ELSE
508  att => nc_make_att(name='units',values=days_units)
509  var => add(var,att)
510 
511  att => nc_make_att(name='time_zone',values='none')
512  var => add(var,att)
513  END IF
514 
515  END FUNCTION itime_object_nest
516 !====================================================================
517 
518 END Module mod_nesting
character(len=160) ncnest_node_files
type(nest_data), dimension(:), pointer ncnest_data
character(len=80) casename
Definition: mod_main.f90:116
real(sp), dimension(:), allocatable, target d
Definition: mod_main.f90:1132
subroutine archive_nest_wave
integer kb_l
type(ncvar), pointer var_u
Definition: mod_nesting.f90:96
subroutine get_output_file_interval(STRING, INTERVAL)
real(sp), dimension(:), allocatable wnode_nest
Definition: mod_nesting.f90:90
type(ncvar) function, pointer itime_object_nest(use_mjd, DIM, size)
integer, parameter nmlunit
Definition: mod_main.f90:926
type(ncvar), pointer var_time2
real(sp), dimension(:,:), allocatable v_nest_l
Definition: mod_nesting.f90:84
integer, parameter dbg_scl
Definition: mod_utils.f90:67
logical function dbg_set(vrb)
Definition: mod_utils.f90:182
real(sp), dimension(:), allocatable ua_nest
Definition: mod_nesting.f90:79
subroutine namelist
Definition: namelist.f90:41
real(sp), dimension(:,:), allocatable s1_nest_l
Definition: mod_nesting.f90:85
logical ncnest_on
integer ncnest_blocksize
type(ncvar), pointer var_time1
integer kbm1_l
subroutine set_var(NOW, UA, VA, EL, U, V, S1, T1, HYW)
type(time) time_interval
subroutine name_list_initialize_nest
subroutine set_var_wave(NOW, HSC1, TPEAK, DIRDEG1)
logical nesting_on
type(ncvar), pointer var_v
Definition: mod_nesting.f90:97
type(ncvar), pointer var_wnode
real(sp), dimension(:,:), allocatable hyw_nest_l
Definition: mod_nesting.f90:86
character(len=80) nesting_file_name
type(ncvar), pointer var_s1
Definition: mod_nesting.f90:98
real(sp), dimension(:), allocatable wcell_nest
Definition: mod_nesting.f90:90
type(ncvar), pointer var_el
Definition: mod_nesting.f90:95
real(sp), dimension(:), allocatable va_nest
Definition: mod_nesting.f90:79
type(nest_data), pointer nesting_data
Definition: mod_nesting.f90:70
type(grid), dimension(:), pointer ncnest_grids
subroutine warning(ER1, ER2, ER3, ER4)
Definition: mod_utils.f90:251
subroutine name_list_read_nest
type(ncvar), pointer var_va
Definition: mod_nesting.f90:94
real(sp), dimension(:,:), allocatable hyw_nest
Definition: mod_nesting.f90:82
real(sp), dimension(:), allocatable el_nest
Definition: mod_nesting.f90:79
subroutine fopen(IUNIT, INSTR, IOPT)
Definition: mod_utils.f90:1577
real(sp), dimension(:,:), allocatable u_nest_l
Definition: mod_nesting.f90:84
type(time) interval_time_ncnest
subroutine open_nesting_file
type(grid), pointer nesting_grid
Definition: mod_nesting.f90:69
real(sp), dimension(:,:), allocatable v_nest
Definition: mod_nesting.f90:80
real(sp), dimension(:), allocatable, target h_l
Definition: mod_nesting.f90:88
subroutine fatal_error(ER1, ER2, ER3, ER4)
Definition: mod_utils.f90:230
real(sp), dimension(:,:), allocatable s1_nest
Definition: mod_nesting.f90:81
type(ncvar), pointer var_t1
Definition: mod_nesting.f90:99
integer ncnest_num
integer nesting_blocksize
real(sp), dimension(:,:), allocatable t1_nest_l
Definition: mod_nesting.f90:85
type(ncvar), pointer var_hyw
character(len=80) ncnest_out_interval
integer, parameter dbg_io
Definition: mod_utils.f90:66
type(ncfile), pointer nesting_file
Definition: mod_nesting.f90:71
type(ncvar), pointer var_wcell
integer ipt
Definition: mod_main.f90:922
integer, parameter dbg_sbr
Definition: mod_utils.f90:69
type(ncvar), pointer var_ua
Definition: mod_nesting.f90:93
character(len=80) nesting_type
subroutine update_float_time_nest(VAR, NOW)
subroutine name_list_print_nest
subroutine archive_nest
real(sp), dimension(:,:), allocatable u_nest
Definition: mod_nesting.f90:80
real(sp), dimension(:,:), allocatable, target zz1_l
Definition: mod_nesting.f90:88
real(sp), dimension(:,:), allocatable t1_nest
Definition: mod_nesting.f90:81
subroutine update_itime_nest(VAR1, VAR2, NOW)
character(len=80), dimension(:), allocatable ncnest_fnames
integer function time2ncitime_nest(MJD, D, MS)
real(sp), dimension(:,:), allocatable, target zz_l
Definition: mod_nesting.f90:88
integer, parameter dbg_log
Definition: mod_utils.f90:65
real(sp), dimension(:), allocatable, target h1_l
Definition: mod_nesting.f90:88
type(ncvar) function, pointer float_time_object_nest(use_mjd, DIM, size)