24 use platform_mod,
only: r4_kind, r8_kind, fms_path_len, fms_file_len
26 use constants_mod,
only: deg_to_rad
28 use mpp_mod,
only : input_nml_file
36 set_override_region, &
38 no_region, inside_region, outside_region, &
45 use time_manager_mod,
only:
time_type,
OPERATOR(>),
OPERATOR(<)
48 get_mosaic_tile_file, file_exists, get_instance_filename
50 use fms_string_utils_mod,
only:
string
56 #include<file_version.h>
61 character(len=3) :: gridname
62 character(len=128) :: fieldname_code
63 character(len=128) :: fieldname_file
64 character(len=FMS_PATH_LEN) :: file_name
65 character(len=128) :: interpol_method
66 logical :: ext_weights
67 character(len=128) :: ext_weights_file_name
68 character(len=128) :: ext_weights_source
69 real(FMS_DATA_OVERRIDE_KIND_) :: factor
70 real(FMS_DATA_OVERRIDE_KIND_) :: lon_start, lon_end, lat_start, lat_end
71 integer :: region_type
72 logical :: multifile = .false.
73 character(len=FMS_PATH_LEN) :: prev_file_name
74 character(len=FMS_PATH_LEN) :: next_file_name
75 type(time_type),
dimension(:),
allocatable :: time_records
76 type(time_type),
dimension(:),
allocatable :: time_prev_records
77 type(time_type),
dimension(:),
allocatable :: time_next_records
83 character(len=3) :: gridname
84 character(len=128) :: fieldname
88 type(horiz_interp_type),
allocatable :: horz_interp(:)
90 integer :: comp_domain(4)
92 real(FMS_DATA_OVERRIDE_KIND_),
allocatable :: lon_in(:)
93 real(FMS_DATA_OVERRIDE_KIND_),
allocatable :: lat_in(:)
94 logical,
allocatable :: need_compute(:)
96 integer :: window_size(2)
97 integer :: is_src, ie_src, js_src, je_src
98 end type override_type
104 type fmsexternalweights_type
105 character(len=:),
allocatable :: weight_filename
106 type(horiz_interp_type) :: horiz_interp
107 end type fmsexternalweights_type
109 integer,
parameter :: lkind = fms_data_override_kind_
110 integer,
parameter :: max_table=100, max_array=100
112 integer :: table_size
113 integer :: nweight_files
114 type(fmsExternalWeights_type),
allocatable,
target :: external_weights(:)
115 logical :: module_is_initialized = .false.
117 type(domain2D) :: ocn_domain,atm_domain,lnd_domain, ice_domain
118 type(domainUG) :: lnd_domainUG
120 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
target,
allocatable :: lon_local_ocn, lat_local_ocn
121 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
target,
allocatable :: lon_local_atm, lat_local_atm
122 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
target,
allocatable :: lon_local_ice, lat_local_ice
123 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
target,
allocatable :: lon_local_lnd, lat_local_lnd
124 real(FMS_DATA_OVERRIDE_KIND_) :: min_glo_lon_ocn, max_glo_lon_ocn
125 real(FMS_DATA_OVERRIDE_KIND_) :: min_glo_lon_atm, max_glo_lon_atm
126 real(FMS_DATA_OVERRIDE_KIND_) :: min_glo_lon_lnd, max_glo_lon_lnd
127 real(FMS_DATA_OVERRIDE_KIND_) :: min_glo_lon_ice, max_glo_lon_ice
128 integer :: num_fields = 0
130 type(data_type),
dimension(:),
allocatable :: data_table
132 type(data_type) :: default_table
133 type(override_type),
dimension(max_array) :: override_array
134 type(override_type) :: default_array
135 logical :: debug_data_override
136 logical :: grid_center_bug = .false.
137 logical :: reproduce_null_char_bug = .false.
141 logical :: use_center_grid_points=.false.
146 logical :: use_data_table_yaml = .false.
148 namelist /data_override_nml/ debug_data_override, grid_center_bug, reproduce_null_char_bug, use_data_table_yaml, &
149 use_center_grid_points
151 public :: data_override_init_impl_, data_override_unset_atm_, data_override_unset_ocn_, &
152 & data_override_unset_lnd_, data_override_unset_ice_, data_override_0d_, &
153 & data_override_2d_, data_override_3d_, data_override_ug_1d_, &
154 & data_override_ug_2d_
168 subroutine data_override_init_impl_(Atm_domain_in, Ocean_domain_in, Ice_domain_in, Land_domain_in, Land_domainUG_in)
169 type (domain2d),
intent(in),
optional :: Atm_domain_in
170 type (domain2d),
intent(in),
optional :: Ocean_domain_in
171 type (domain2d),
intent(in),
optional :: Ice_domain_in
172 type (domain2d),
intent(in),
optional :: Land_domain_in
173 type(domainUG) ,
intent(in),
optional :: Land_domainUG_in
175 character(len=18),
parameter :: grid_file =
'INPUT/grid_spec.nc'
176 integer :: i, iunit, io_status, ierr, use_get_grid_version
177 logical :: atm_on, ocn_on, lnd_on, ice_on, lndUG_on
179 type(FmsNetcdfFile_t) :: fileobj
181 debug_data_override = .false.
183 read (input_nml_file, data_override_nml, iostat=io_status)
186 write(iunit, data_override_nml)
189 if (grid_center_bug)
then
190 call mpp_error(fatal,
"data_override_init: You have overridden the default value of " // &
191 "grid_center_bug and set it to .true. in data_override_nml. This was a temporary workaround " // &
192 "that is no longer supported. Please remove this namelist variable.")
195 if (use_data_table_yaml)
then
196 call mpp_error(note,
"data_override_init: You are using the yaml version of the data table.")
198 call mpp_error(note,
"data_override_init: You are using the legacy version of the data table.")
201 atm_on =
PRESENT(atm_domain_in)
202 ocn_on =
PRESENT(ocean_domain_in)
203 lnd_on =
PRESENT(land_domain_in)
204 ice_on =
PRESENT(ice_domain_in)
205 lndug_on =
PRESENT(land_domainug_in)
206 if(.not. module_is_initialized)
then
207 atm_domain = null_domain2d
208 ocn_domain = null_domain2d
209 lnd_domain = null_domain2d
210 ice_domain = null_domain2d
211 lnd_domainug = null_domainug
213 if (atm_on) atm_domain = atm_domain_in
214 if (ocn_on) ocn_domain = ocean_domain_in
215 if (lnd_on) lnd_domain = land_domain_in
216 if (ice_on) ice_domain = ice_domain_in
217 if (lndug_on) lnd_domainug = land_domainug_in
219 if(.not. module_is_initialized)
then
224 default_table%gridname =
'non'
225 default_table%fieldname_code =
'none'
226 default_table%fieldname_file =
'none'
227 default_table%file_name =
'none'
228 default_table%factor = 1._lkind
229 default_table%interpol_method =
'bilinear'
230 default_table%multifile = .false.
231 default_table%prev_file_name =
''
232 default_table%next_file_name =
''
235 if (use_data_table_yaml)
then
236 if (file_exists(
"data_table")) &
237 call mpp_error(fatal,
"You cannot have the legacy data_table if use_data_table_yaml=.true.")
238 call read_table_yaml(data_table)
239 allocate(external_weights(table_size))
242 if (file_exists(
"data_table.yaml"))&
243 call mpp_error(fatal,
"You cannot have the yaml data_table if use_data_table_yaml=.false.")
244 allocate(data_table(max_table))
246 data_table(i) = default_table
248 call read_table(data_table)
251 if (file_exists(
"data_table.yaml"))&
252 call mpp_error(fatal,
"You cannot have the yaml data_table if use_data_table_yaml=.false.")
254 if (use_data_table_yaml)
then
255 call mpp_error(fatal,
"You cannot have use_data_table_yaml=.true. without compiling with -Duse_yaml")
258 allocate(data_table(max_table))
260 data_table(i) = default_table
262 call read_table(data_table)
267 default_array%gridname =
'NONE'
268 default_array%fieldname =
'NONE'
269 default_array%t_index = -1
270 default_array%dims = -1
271 default_array%comp_domain = -1
273 override_array(i) = default_array
278 module_is_initialized = .true.
280 if ( .NOT. (atm_on .or. ocn_on .or. lnd_on .or. ice_on .or. lndug_on))
return
281 if (table_size .eq. 0)
then
282 call mpp_error(note,
"data_table is empty, not doing any data_overrides")
288 inquire (file=trim(grid_file), opened=file_open)
289 if(file_open)
call mpp_error(fatal, trim(grid_file)//
' already opened')
291 if(.not.
open_file(fileobj, grid_file,
'read' ))
then
292 call mpp_error(fatal,
'data_override_mod: Error in opening file '//trim(grid_file))
295 if(variable_exists(fileobj,
"x_T" ) .OR. variable_exists(fileobj,
"geolon_t" ) )
then
296 use_get_grid_version = 1
298 else if(variable_exists(fileobj,
"ocn_mosaic_file" ) .OR. variable_exists(fileobj,
"gridfiles" ) )
then
299 use_get_grid_version = 2
300 if(variable_exists(fileobj,
"gridfiles" ) )
then
301 if(count_ne_1((ocn_on .OR. ice_on), lnd_on, atm_on))
call mpp_error(fatal,
'data_override_mod: the grid file ' //&
302 'is a solo mosaic, one and only one of atm_on, lnd_on or ice_on/ocn_on should be true')
305 call mpp_error(fatal,
'data_override_mod: none of x_T, geolon_t, ocn_mosaic_file or gridfiles exist in '// &
309 if(use_get_grid_version .EQ. 1)
then
310 if (atm_on .and. .not.
allocated(lon_local_atm) )
then
312 min_glo_lon_atm, max_glo_lon_atm )
314 if (ocn_on .and. .not.
allocated(lon_local_ocn) )
then
316 min_glo_lon_ocn, max_glo_lon_ocn )
319 if (lnd_on .and. .not.
allocated(lon_local_lnd) )
then
321 min_glo_lon_lnd, max_glo_lon_lnd )
324 if (ice_on .and. .not.
allocated(lon_local_ice) )
then
326 min_glo_lon_ice, max_glo_lon_ice )
329 if (atm_on .and. .not.
allocated(lon_local_atm) )
then
331 min_glo_lon_atm, max_glo_lon_atm )
334 if (ocn_on .and. .not.
allocated(lon_local_ocn) )
then
336 min_glo_lon_ocn, max_glo_lon_ocn, use_center_grid_points)
339 if (lnd_on .and. .not.
allocated(lon_local_lnd) )
then
341 min_glo_lon_lnd, max_glo_lon_lnd )
344 if (ice_on .and. .not.
allocated(lon_local_ice) )
then
346 min_glo_lon_ice, max_glo_lon_ice, use_center_grid_points)
349 if(use_get_grid_version .EQ. 2)
then
352 end subroutine data_override_init_impl_
366 function count_ne_1(in_1, in_2, in_3)
367 logical,
intent(in) :: in_1
368 logical,
intent(in) :: in_2
369 logical,
intent(in) :: in_3
370 logical :: count_ne_1
372 count_ne_1 = .not.(in_1.NEQV.in_2.NEQV.in_3) .OR. (in_1.AND.in_2.AND.in_3)
373 end function count_ne_1
375 subroutine read_table(data_table)
376 type(data_type),
dimension(max_table),
intent(inout) :: data_table
379 integer :: ntable_lima
380 integer :: ntable_new
384 integer :: index_1col, index_2col
385 character(len=256) :: record
386 type(data_type) :: data_entry
389 logical :: table_exists
390 character(len=128) :: region, region_type
395 inquire(file=
'data_table', exist=table_exists)
396 if (.not. table_exists)
then
397 call mpp_error(note,
'data_override_mod: File data_table does not exist.')
402 open(newunit=iunit, file=
'data_table', action=
'READ', iostat=io_status)
403 if(io_status/=0)
call mpp_error(fatal,
'data_override_mod: Error in opening file data_table.')
409 do while (ntable <= max_table)
410 read(iunit,
'(a)',
end=100) record
411 if (record(1:1) ==
'#') cycle
412 if (record(1:10) ==
' ') cycle
414 if(index(lowercase(record),
"inside_region") .ne. 0 .or. index(lowercase(record),
"outside_region") .ne. 0)
then
415 if(index(lowercase(record),
".false.") .ne. 0 .or. index(lowercase(record),
".true.") .ne. 0 )
then
416 ntable_lima = ntable_lima + 1
417 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
418 data_entry%file_name, ongrid, data_entry%factor, region, region_type
420 data_entry%interpol_method =
'none'
422 data_entry%interpol_method =
'bilinear'
425 ntable_new=ntable_new+1
426 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
427 data_entry%file_name, data_entry%interpol_method, data_entry%factor, region, &
430 if (index(data_entry%file_name,
":") .ne. 0)
then
431 data_entry%multifile = .true.
432 index_1col = index(data_entry%file_name,
":")
433 index_2col = index(data_entry%file_name(index_1col+1:),
":")
434 if (index_2col .eq. 0)
call mpp_error(fatal,
"data_override: when bridging over forcing files, " &
435 //
"central forcing files must be preceded AND followed by the column (:) separator")
436 data_entry%prev_file_name = data_entry%file_name(1:index_1col-1)
437 data_entry%next_file_name = data_entry%file_name(index_1col+index_2col+1:)
439 data_entry%file_name = data_entry%file_name(index_1col+1:index_1col+index_2col-1)
441 data_entry%multifile = .false.
442 data_entry%prev_file_name =
""
443 data_entry%next_file_name =
""
445 if (data_entry%interpol_method ==
'default')
then
446 data_entry%interpol_method = default_table%interpol_method
448 if (.not.(data_entry%interpol_method ==
'default' .or. &
449 data_entry%interpol_method ==
'bicubic' .or. &
450 data_entry%interpol_method ==
'bilinear' .or. &
451 data_entry%interpol_method ==
'none'))
then
453 write(sunit,*)
" gridname is ", trim(data_entry%gridname)
454 write(sunit,*)
" fieldname_code is ", trim(data_entry%fieldname_code)
455 write(sunit,*)
" fieldname_file is ", trim(data_entry%fieldname_file)
456 write(sunit,*)
" file_name is ", trim(data_entry%file_name)
457 write(sunit,*)
" factor is ", data_entry%factor
458 write(sunit,*)
" interpol_method is ", trim(data_entry%interpol_method)
459 call mpp_error(fatal,
'data_override_mod: invalid last entry in data_override_table, ' &
460 //
'its value should be "default", "bicubic", "bilinear" or "none" ')
463 if( trim(region_type) ==
"inside_region" )
then
464 data_entry%region_type = inside_region
465 else if( trim(region_type) ==
"outside_region" )
then
466 data_entry%region_type = outside_region
468 call mpp_error(fatal,
'data_override_mod: region type should be inside_region or outside_region')
470 if (data_entry%file_name ==
"")
call mpp_error(fatal, &
471 "data_override: filename not given in data_table when region_type is not NO_REGION")
472 if(data_entry%fieldname_file ==
"")
call mpp_error(fatal, &
473 "data_override: fieldname_file must be specified in data_table when region_type is not NO_REGION")
474 if( trim(data_entry%interpol_method) ==
'none')
call mpp_error(fatal, &
475 "data_override(data_override_init): ongrid must be false when region_type is not NO_REGION")
476 read(region,*) data_entry%lon_start, data_entry%lon_end, data_entry%lat_start, data_entry%lat_end
478 if(data_entry%lon_end .LE. data_entry%lon_start)
call mpp_error(fatal, &
479 "data_override: lon_end should be greater than lon_start")
480 if(data_entry%lat_end .LE. data_entry%lat_start)
call mpp_error(fatal, &
481 "data_override: lat_end should be greater than lat_start")
483 else if (index(lowercase(record),
".false.") .ne. 0 .or. index(lowercase(record),
".true.") .ne. 0 )
then
484 ntable_lima = ntable_lima + 1
485 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
486 data_entry%file_name, ongrid, data_entry%factor
487 if (index(data_entry%file_name,
":") .ne. 0)
then
488 data_entry%multifile = .true.
489 index_1col = index(data_entry%file_name,
":")
490 index_2col = index(data_entry%file_name(index_1col+1:),
":")
491 if (index_2col .eq. 0)
call mpp_error(fatal,
"data_override: when bridging over forcing files, " &
492 //
"central forcing files must be preceded AND followed by the column (:) separator")
493 data_entry%prev_file_name = data_entry%file_name(1:index_1col-1)
494 data_entry%next_file_name = data_entry%file_name(index_1col+index_2col+1:)
496 data_entry%file_name = data_entry%file_name(index_1col+1:index_1col+index_2col-1)
498 data_entry%multifile = .false.
499 data_entry%prev_file_name =
""
500 data_entry%next_file_name =
""
503 data_entry%interpol_method =
'none'
505 data_entry%interpol_method =
'bilinear'
507 data_entry%lon_start = 0.0_lkind
508 data_entry%lon_end = -1.0_lkind
509 data_entry%lat_start = 0.0_lkind
510 data_entry%lat_end = -1.0_lkind
511 data_entry%region_type = no_region
513 ntable_new=ntable_new+1
514 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
515 data_entry%file_name, data_entry%interpol_method, data_entry%factor
516 if (index(data_entry%file_name,
":") .ne. 0)
then
517 index_1col = index(data_entry%file_name,
":")
518 index_2col = index(data_entry%file_name(index_1col+1:),
":")
519 data_entry%multifile = .true.
520 if (index_2col .eq. 0)
call mpp_error(fatal,
"data_override: when bridging over forcing files, " &
521 //
"central forcing files must be preceded AND followed by the column (:) separator")
522 data_entry%prev_file_name = data_entry%file_name(1:index_1col-1)
523 data_entry%next_file_name = data_entry%file_name(index_1col+index_2col+1:)
525 data_entry%file_name = data_entry%file_name(index_1col+1:index_1col+index_2col-1)
527 data_entry%multifile = .false.
528 data_entry%prev_file_name =
""
529 data_entry%next_file_name =
""
531 if (data_entry%interpol_method ==
'default')
then
532 data_entry%interpol_method = default_table%interpol_method
534 if (.not.(data_entry%interpol_method ==
'default' .or. &
535 data_entry%interpol_method ==
'bicubic' .or. &
536 data_entry%interpol_method ==
'bilinear' .or. &
537 data_entry%interpol_method ==
'none'))
then
539 write(sunit,*)
" gridname is ", trim(data_entry%gridname)
540 write(sunit,*)
" fieldname_code is ", trim(data_entry%fieldname_code)
541 write(sunit,*)
" fieldname_file is ", trim(data_entry%fieldname_file)
542 write(sunit,*)
" file_name is ", trim(data_entry%file_name)
543 write(sunit,*)
" factor is ", data_entry%factor
544 write(sunit,*)
" interpol_method is ", trim(data_entry%interpol_method)
545 call mpp_error(fatal,
'data_override_mod: invalid last entry in data_override_table, ' &
546 //
'its value should be "default", "bicubic", "bilinear" or "none" ')
548 data_entry%lon_start = 0.0_lkind
549 data_entry%lon_end = -1.0_lkind
550 data_entry%lat_start = 0.0_lkind
551 data_entry%lat_end = -1.0_lkind
552 data_entry%region_type = no_region
554 data_entry%ext_weights = .false.
555 data_table(ntable) = data_entry
557 call mpp_error(fatal,
'too many enries in data_table')
558 99
call mpp_error(fatal,
'error in data_table format')
561 if(ntable_new*ntable_lima /= 0)
call mpp_error(fatal, &
562 'data_override_mod: New and old formats together in same data_table not supported')
563 close(iunit, iostat=io_status)
564 if(io_status/=0)
call mpp_error(fatal,
'data_override_mod: Error in closing file data_table')
565 end subroutine read_table
569 subroutine read_table_yaml(data_table)
570 type(data_type),
dimension(:),
allocatable,
intent(out) :: data_table
572 integer,
allocatable :: entry_id(:)
573 integer :: sub_block_id(1), sub2_block_id(1)
574 integer :: nentries, mentries
576 character(len=50) :: buffer
577 character(len=FMS_FILE_LEN) :: filename
581 call get_instance_filename(
"data_table.yaml", filename)
582 if (index(trim(filename),
"ens_") .ne. 0)
then
583 if (file_exists(filename) .and. file_exists(
"data_table.yaml")) &
584 call mpp_error(fatal,
"Both data_table.yaml and "//trim(filename)//
" exists, pick one!")
588 if (.not. file_exists(filename)) filename =
"data_table.yaml"
593 if (file_id==999)
then
597 allocate(data_table(nentries))
598 allocate(entry_id(nentries))
604 call check_for_valid_gridname(data_table(i)%gridname)
605 call get_value_from_key(file_id, entry_id(i),
"fieldname_in_model", data_table(i)%fieldname_code)
607 mentries =
get_num_blocks(file_id,
"override_file", parent_block_id=entry_id(i))
608 data_table(i)%file_name =
""
609 data_table(i)%fieldname_file =
""
610 data_table(i)%interpol_method =
"none"
611 data_table(i)%multifile = .false.
612 data_table(i)%ext_weights = .false.
613 data_table(i)%region_type = no_region
614 data_table(i)%prev_file_name =
""
615 data_table(i)%next_file_name =
""
616 data_table(i)%ext_weights_file_name =
""
617 data_table(i)%ext_weights_source =
""
620 if (mentries .eq. 0) cycle
622 if(mentries.gt.1)
call mpp_error(fatal,
"Too many override_file blocks in data table. "//&
623 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
624 trim(data_table(i)%fieldname_code))
625 call get_block_ids(file_id,
"override_file", sub_block_id, parent_block_id=entry_id(i))
627 call get_value_from_key(file_id, sub_block_id(1),
"file_name", data_table(i)%file_name)
628 call get_value_from_key(file_id, sub_block_id(1),
"fieldname_in_file", data_table(i)%fieldname_file)
629 call get_value_from_key(file_id, sub_block_id(1),
"interp_method", data_table(i)%interpol_method)
630 call check_interpol_method(data_table(i)%interpol_method, data_table(i)%file_name, &
631 & data_table(i)%fieldname_file)
633 mentries =
get_num_blocks(file_id,
"multi_file", parent_block_id=sub_block_id(1))
634 if(mentries.gt.1)
call mpp_error(fatal,
"Too many multi_file blocks in tata table. "//&
635 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
636 trim(data_table(i)%fieldname_code))
638 if(mentries.gt.0) data_table(i)%multifile = .true.
640 if (data_table(i)%multifile)
then
641 call get_block_ids(file_id,
"multi_file", sub2_block_id, parent_block_id=sub_block_id(1))
642 call get_value_from_key(file_id, sub2_block_id(1),
"prev_file_name", data_table(i)%prev_file_name)
643 call get_value_from_key(file_id, sub2_block_id(1),
"next_file_name", data_table(i)%next_file_name)
644 if (trim(data_table(i)%prev_file_name) .eq.
"" .and. trim(data_table(i)%next_file_name) .eq.
"") &
645 call mpp_error(fatal,
"The prev_file_name and next_file_name must be present if is_multi_file. "//&
646 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
647 trim(data_table(i)%fieldname_code))
650 mentries =
get_num_blocks(file_id,
"external_weights", parent_block_id=sub_block_id(1))
651 if(mentries.gt.1)
call mpp_error(fatal,
"Too many external_weight blocks in data table. "//&
652 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
653 trim(data_table(i)%fieldname_code))
655 if(mentries.gt.0) data_table(i)%ext_weights = .true.
657 if (data_table(i)%ext_weights)
then
658 call get_block_ids(file_id,
"external_weights", sub2_block_id, parent_block_id=sub_block_id(1))
659 call get_value_from_key(file_id, sub2_block_id(1),
"file_name", data_table(i)%ext_weights_file_name)
660 call get_value_from_key(file_id, sub2_block_id(1),
"source", data_table(i)%ext_weights_source)
661 if (trim(data_table(i)%ext_weights_file_name) .eq.
"" .and. trim(data_table(i)%ext_weights_source) .eq.
"") &
662 call mpp_error(fatal,
"The file_name and source must be present when using external weights"//&
663 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
664 trim(data_table(i)%fieldname_code))
667 mentries =
get_num_blocks(file_id,
"subregion", parent_block_id=entry_id(i))
668 if(mentries.gt.1)
call mpp_error(fatal,
"Too many subregion blocks in data table. "//&
669 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
670 trim(data_table(i)%fieldname_code))
673 if(mentries.gt.0)
then
674 call get_block_ids(file_id,
"subregion", sub_block_id, parent_block_id=entry_id(i))
678 call check_and_set_region_type(buffer, data_table(i)%region_type)
679 if (data_table(i)%region_type .ne. no_region)
then
680 call get_value_from_key(file_id, sub_block_id(1),
"lon_start", data_table(i)%lon_start)
682 call get_value_from_key(file_id, sub_block_id(1),
"lat_start", data_table(i)%lat_start)
684 call check_valid_lat_lon(data_table(i)%lon_start, data_table(i)%lon_end, &
685 data_table(i)%lat_start, data_table(i)%lat_end)
690 table_size = nentries
691 end subroutine read_table_yaml
694 subroutine check_for_valid_gridname(gridname)
695 character(len=*),
intent(in) :: gridname
697 select case(trim(gridname))
698 case (
"OCN",
"ATM",
"LND",
"ICE")
700 call mpp_error(fatal, trim(gridname)//
" is not a valid gridname. "//&
701 "The acceptable values are OCN ATM LND and ICE. Check your data_table.yaml")
703 end subroutine check_for_valid_gridname
706 subroutine check_interpol_method(interp_method, filename, fieldname)
707 character(len=*),
intent(in) :: interp_method
708 character(len=*),
intent(in) :: filename
709 character(len=*),
intent(in) :: fieldname
711 select case(trim(interp_method))
712 case (
"bicubic",
"bilinear")
713 if (trim(filename) .eq.
"" .or. trim(fieldname) .eq.
"")
call mpp_error(fatal, &
714 "The file_name and the fieldname_file must be set if using the bicubic or bilinear interpolation method."//&
715 " Check your data_table.yaml")
717 if (trim(filename) .ne.
"" )
then
718 if (trim(fieldname) .eq.
"")
call mpp_error(fatal, &
719 "If the interpol_method is none and file_name is specified (ongrid case), "//&
720 "you must also specify the fieldname_file")
723 call mpp_error(fatal, trim(interp_method)//
" is not a valid interp method. "//&
724 "The acceptable values are bilinear and bicubic")
726 end subroutine check_interpol_method
730 subroutine check_and_set_region_type(region_type_str, region_type_int)
731 character(len=*),
intent(in) :: region_type_str
732 integer,
intent(out) :: region_type_int
734 select case(trim(region_type_str))
735 case (
"inside_region")
736 region_type_int = inside_region
737 case (
"outside_region")
738 region_type_int = outside_region
740 region_type_int = no_region
742 call mpp_error(fatal, trim(region_type_str)//
" is not a valid region type. "//&
743 "The acceptable values are inside_region and outside_regioon. Check your data_table.yaml")
745 end subroutine check_and_set_region_type
749 subroutine check_valid_lat_lon(lon_start, lon_end, lat_start, lat_end)
750 real(FMS_DATA_OVERRIDE_KIND_),
intent(in) :: lon_start
751 real(FMS_DATA_OVERRIDE_KIND_),
intent(in) :: lon_end
752 real(FMS_DATA_OVERRIDE_KIND_),
intent(in) :: lat_start
753 real(FMS_DATA_OVERRIDE_KIND_),
intent(in) :: lat_end
755 if (lon_start > lon_end)
call mpp_error(fatal, &
756 "lon_start:"//
string(lon_start)//
" is greater than lon_end"//
string(lon_end)//&
757 ". Check your data_table.yaml.")
759 if (lat_start > lat_end)
call mpp_error(fatal, &
760 "lat_start:"//
string(lat_start)//
" is greater than lat_end:"//
string(lat_end)//&
761 ". Check your data_table.yaml.")
762 end subroutine check_valid_lat_lon
765 subroutine data_override_unset_atm_
766 atm_domain = null_domain2d
767 if (
allocated(lon_local_atm))
deallocate(lon_local_atm)
768 if (
allocated(lat_local_atm))
deallocate(lat_local_atm)
771 subroutine data_override_unset_ocn_
772 ocn_domain = null_domain2d
773 if (
allocated(lon_local_ocn))
deallocate(lon_local_ocn)
774 if (
allocated(lat_local_ocn))
deallocate(lat_local_ocn)
777 subroutine data_override_unset_lnd_
778 lnd_domain = null_domain2d
779 if (
allocated(lon_local_lnd))
deallocate(lon_local_lnd)
780 if (
allocated(lat_local_lnd))
deallocate(lat_local_lnd)
783 subroutine data_override_unset_ice_
784 ice_domain = null_domain2d
785 if (
allocated(lon_local_ice))
deallocate(lon_local_ice)
786 if (
allocated(lat_local_ice))
deallocate(lat_local_ice)
790 subroutine get_domain(gridname, domain, comp_domain)
791 character(len=3),
intent(in) :: gridname
792 type(domain2D),
intent(inout) :: domain
793 integer,
intent(out),
optional :: comp_domain(4)
795 domain = null_domain2d
796 select case (gridname)
806 call mpp_error(fatal,
'error in data_override get_domain')
808 if(domain .EQ. null_domain2d)
call mpp_error(fatal,
'data_override: failure in get_domain')
809 if(
present(comp_domain)) &
811 end subroutine get_domain
814 subroutine get_domainug(gridname, UGdomain, comp_domain)
815 character(len=3),
intent(in) :: gridname
816 type(domainUG),
intent(inout) :: UGdomain
817 integer,
intent(out),
optional :: comp_domain(4)
818 type(domain2D),
pointer :: SGdomain => null()
820 ugdomain = null_domainug
821 select case (gridname)
823 ugdomain = lnd_domainug
825 call mpp_error(fatal,
'error in data_override get_domain')
828 if(
present(comp_domain)) &
829 call mpp_get_ug_sg_domain(ugdomain,sgdomain)
831 end subroutine get_domainug
835 subroutine data_override_0d_(gridname,fieldname_code,data_out,time,override,data_index)
836 character(len=3),
intent(in) :: gridname
837 character(len=*),
intent(in) :: fieldname_code
839 logical,
intent(out),
optional :: override
840 type(time_type),
intent(in) :: time
841 real(FMS_DATA_OVERRIDE_KIND_),
intent(out) :: data_out
842 integer,
intent(in),
optional :: data_index
844 type(time_type) :: first_record
845 type(time_type) :: last_record
846 character(len=FMS_PATH_LEN) :: filename
847 character(len=FMS_PATH_LEN) :: prevfilename
848 character(len=FMS_PATH_LEN) :: nextfilename
849 character(len=128) :: fieldname
852 integer :: prev_dims(4)
853 integer :: next_dims(4)
855 integer :: id_time_prev=-1
856 integer :: id_time_next=-1
857 integer :: curr_position
859 real(FMS_DATA_OVERRIDE_KIND_) :: factor
862 if(.not.module_is_initialized) &
863 call mpp_error(fatal,
'Error: need to call data_override_init first')
866 if(
PRESENT(override)) override = .false.
867 if (
present(data_index))
then
872 if( trim(gridname) /= trim(data_table(i)%gridname)) cycle
873 if( trim(fieldname_code) /= trim(data_table(i)%fieldname_code)) cycle
877 if(index1 .eq. -1)
then
878 if(debug_data_override) &
879 call mpp_error(warning,
'this field is NOT found in data_table: '//trim(fieldname_code))
884 fieldname = data_table(index1)%fieldname_file
885 factor = data_table(index1)%factor
886 multifile = data_table(index1)%multifile
888 if(fieldname ==
"")
then
890 if(
PRESENT(override)) override = .true.
893 filename = data_table(index1)%file_name
894 if (filename ==
"")
call mpp_error(fatal,
'data_override: filename not given in data_table')
895 if (multifile) prevfilename = data_table(index1)%prev_file_name
896 if (multifile) nextfilename = data_table(index1)%next_file_name
902 if(num_fields > 0 )
then
904 if(trim(override_array(i)%gridname) /= trim(gridname)) cycle
905 if(trim(override_array(i)%fieldname) /= trim(fieldname_code)) cycle
911 if(curr_position < 0)
then
912 num_fields = num_fields + 1
913 curr_position = num_fields
915 override_array(curr_position)%fieldname = fieldname_code
916 override_array(curr_position)%gridname = gridname
918 if(id_time<0)
call mpp_error(fatal,
'data_override:field not found in init_external_field 1')
919 override_array(curr_position)%t_index = id_time
922 id_time = override_array(curr_position)%t_index
928 if_multi1:
if (multifile)
then
930 if_prev1:
if (trim(prevfilename) /=
'')
then
935 if ((prev_dims(1) .ne. dims(1)) .or. (prev_dims(2) .ne. dims(2)) .or. &
936 (prev_dims(3) .ne. dims(3)))
then
937 call mpp_error(fatal,
'data_override: dimensions mismatch between consecutive forcing files')
939 allocate(data_table(index1)%time_prev_records(prev_dims(4)))
940 call get_time_axis(id_time_prev,data_table(index1)%time_prev_records)
943 if_next1:
if (trim(nextfilename) /=
'')
then
948 if ((next_dims(1) .ne. dims(1)) .or. (next_dims(2) .ne. dims(2)) .or. &
949 (next_dims(3) .ne. dims(3)))
then
950 call mpp_error(fatal,
'data_override: dimensions mismatch between consecutive forcing files')
952 allocate(data_table(index1)%time_next_records(next_dims(4)))
953 call get_time_axis(id_time_next,data_table(index1)%time_next_records)
963 if_multi2:
if (multifile)
then
965 if (.not.
allocated(data_table(index1)%time_records))
allocate(data_table(index1)%time_records(dims(4)))
968 first_record = data_table(index1)%time_records(1)
969 last_record = data_table(index1)%time_records(dims(4))
971 if_time2:
if (time<first_record)
then
972 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
974 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
975 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
977 elseif (time>last_record)
then
978 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
979 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
980 'data_override: time_interp_external_bridge should only be called to bridge with next file')
990 data_out = data_out*factor
993 if(
PRESENT(override)) override = .true.
995 end subroutine data_override_0d_
998 subroutine data_override_2d_(gridname,fieldname,data_2D,time,override, is_in, ie_in, js_in, je_in)
999 character(len=3),
intent(in) :: gridname
1000 character(len=*),
intent(in) :: fieldname
1001 logical,
intent(out),
optional :: override
1002 type(time_type),
intent(in) :: time
1003 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
intent(inout) :: data_2D
1004 integer,
optional,
intent(in) :: is_in, ie_in, js_in, je_in
1005 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:,:),
allocatable :: data_3D
1010 if(
PRESENT(override)) override = .false.
1012 do i = 1, table_size
1013 if( trim(gridname) /= trim(data_table(i)%gridname)) cycle
1014 if( trim(fieldname) /= trim(data_table(i)%fieldname_code)) cycle
1018 if(index1 .eq. -1)
return
1020 allocate(data_3d(
size(data_2d,1),
size(data_2d,2),1))
1021 data_3d(:,:,1) = data_2d
1022 call data_override_3d_(gridname,fieldname,data_3d,time,override,data_index=index1,&
1023 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in)
1025 data_2d(:,:) = data_3d(:,:,1)
1027 end subroutine data_override_2d_
1030 subroutine data_override_3d_(gridname,fieldname_code,return_data,time,override,data_index, is_in, ie_in, js_in, je_in)
1031 character(len=3),
intent(in) :: gridname
1032 character(len=*),
intent(in) :: fieldname_code
1033 logical,
optional,
intent(out) :: override
1034 type(time_type),
intent(in) :: time
1035 integer,
optional,
intent(in) :: data_index
1036 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:,:),
intent(inout) :: return_data
1037 integer,
optional,
intent(in) :: is_in, ie_in, js_in, je_in
1038 logical,
dimension(:,:,:),
allocatable :: mask_out
1040 character(len=FMS_PATH_LEN) :: filename
1041 character(len=FMS_PATH_LEN) :: filename2
1042 character(len=FMS_PATH_LEN) :: prevfilename
1043 character(len=FMS_PATH_LEN) :: prevfilename2
1044 character(len=FMS_PATH_LEN) :: nextfilename
1045 character(len=FMS_PATH_LEN) :: nextfilename2
1046 character(len=128) :: fieldname
1049 integer :: prev_dims(4)
1050 integer :: next_dims(4)
1053 integer :: id_time_prev=-1
1054 integer :: id_time_next=-1
1055 integer :: axis_sizes(4)
1056 character(len=32) :: axis_names(4)
1057 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
pointer :: lon_local =>null()
1058 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
pointer :: lat_local =>null()
1059 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:),
allocatable :: lon_tmp, lat_tmp
1061 logical :: data_file_is_2D = .false.
1062 logical :: ongrid, use_comp_domain
1063 type(domain2D) :: domain
1064 type(time_type) :: first_record
1065 type(time_type) :: last_record
1066 integer :: curr_position
1067 real(FMS_DATA_OVERRIDE_KIND_) :: factor
1068 integer,
dimension(4) :: comp_domain = 0
1069 integer :: nxd, nyd, nxc, nyc, nwindows
1070 integer :: nwindows_x, ipos, jpos, window_size(2)
1071 integer :: istart, iend, jstart, jend
1072 integer :: isw, iew, jsw, jew
1073 integer :: omp_get_num_threads, window_id
1074 logical :: need_compute
1075 real(FMS_DATA_OVERRIDE_KIND_) :: lat_min, lat_max
1076 integer :: is_src, ie_src, js_src, je_src
1078 logical :: multifile
1079 type(FmsNetcdfFile_t) :: fileobj
1080 integer :: startingi
1082 integer :: startingj
1086 logical :: found_weight_file
1090 use_comp_domain = .false.
1091 if(.not.module_is_initialized) &
1092 call mpp_error(fatal,
'Error: need to call data_override_init first')
1095 if(
PRESENT(override)) override = .false.
1096 if (
present(data_index))
then
1100 do i = 1, table_size
1101 if( trim(gridname) /= trim(data_table(i)%gridname)) cycle
1102 if( trim(fieldname_code) /= trim(data_table(i)%fieldname_code)) cycle
1106 if(index1 .eq. -1)
then
1107 if(debug_data_override) &
1108 call mpp_error(warning,
'this field is NOT found in data_table: '//trim(fieldname_code))
1113 fieldname = data_table(index1)%fieldname_file
1114 factor = data_table(index1)%factor
1115 multifile = data_table(index1)%multifile
1117 if(fieldname ==
"")
then
1118 return_data = factor
1119 if(
PRESENT(override)) override = .true.
1122 filename = data_table(index1)%file_name
1123 if (filename ==
"")
call mpp_error(fatal,
'data_override: filename not given in data_table')
1124 if (multifile) prevfilename = data_table(index1)%prev_file_name
1125 if (multifile) nextfilename = data_table(index1)%next_file_name
1128 ongrid = (data_table(index1)%interpol_method ==
'none')
1133 if(num_fields > 0 )
then
1134 do i = 1, num_fields
1135 if(trim(override_array(i)%gridname) /= trim(gridname)) cycle
1136 if(trim(override_array(i)%fieldname) /= trim(fieldname_code)) cycle
1142 if(curr_position < 0)
then
1143 num_fields = num_fields + 1
1144 curr_position = num_fields
1147 call get_domain(gridname,domain,comp_domain)
1149 nxc = comp_domain(2)-comp_domain(1) + 1
1150 nyc = comp_domain(4)-comp_domain(3) + 1
1153 override_array(curr_position)%fieldname = fieldname_code
1154 override_array(curr_position)%gridname = gridname
1155 override_array(curr_position)%comp_domain = comp_domain
1157 override_array(curr_position)%numthreads = 1
1158 #if defined(_OPENMP)
1159 override_array(curr_position)%numthreads = omp_get_num_threads()
1170 if( nxd ==
size(return_data,1) .AND. nyd ==
size(return_data,2) )
then
1171 use_comp_domain = .false.
1172 else if ( mod(nxc,
size(return_data,1)) ==0 .AND. mod(nyc,
size(return_data,2)) ==0 )
then
1173 use_comp_domain = .true.
1174 nwindows = (nxc/
size(return_data,1))*(nyc/
size(return_data,2))
1177 &
"data_override: data is not on data domain and compute domain is not divisible by size(data)")
1179 override_array(curr_position)%window_size(1) =
size(return_data,1)
1180 override_array(curr_position)%window_size(2) =
size(return_data,2)
1182 window_size = override_array(curr_position)%window_size
1183 override_array(curr_position)%numwindows = nwindows
1184 if( mod(nwindows, override_array(curr_position)%numthreads) .NE. 0 )
then
1185 call mpp_error(fatal,
"data_override: nwindow is not divisible by nthreads")
1187 allocate(override_array(curr_position)%need_compute(nwindows))
1188 override_array(curr_position)%need_compute = .true.
1192 if( data_table(index1)%region_type .NE. no_region )
then
1193 call mpp_error(fatal,.NE.
'data_override: ongrid must be false when region_type NO_REGION')
1197 inquire(file=trim(filename),exist=exists)
1198 if (.not. exists)
then
1199 call get_mosaic_tile_file(filename,filename2,.false.,domain)
1200 filename = filename2
1204 if_multi3:
if (multifile)
then
1205 if_prev3:
if (trim(prevfilename) /=
'')
then
1206 inquire(file=trim(prevfilename),exist=exists)
1207 if (.not. exists)
then
1208 call get_mosaic_tile_file(prevfilename,prevfilename2,.false.,domain)
1209 prevfilename = prevfilename2
1212 if_next3:
if (trim(nextfilename) /=
'')
then
1213 inquire(file=trim(nextfilename),exist=exists)
1214 if (.not. exists)
then
1215 call get_mosaic_tile_file(nextfilename,nextfilename2,.false.,domain)
1216 nextfilename = nextfilename2
1222 id_time =
init_external_field(filename,fieldname,domain=domain,verbose=debug_data_override, &
1223 use_comp_domain=use_comp_domain, nwindows=nwindows, ongrid=ongrid)
1227 if_multi4:
if (multifile)
then
1229 if_prev4:
if (trim(prevfilename) /=
'')
then
1231 verbose=debug_data_override,use_comp_domain=use_comp_domain, &
1232 nwindows = nwindows, ongrid=ongrid)
1236 if ((prev_dims(1) .ne. dims(1)) .or. (prev_dims(2) .ne. dims(2)) .or. &
1237 (prev_dims(3) .ne. dims(3)))
then
1238 call mpp_error(fatal,
'data_override: dimensions mismatch between consecutive forcing files')
1240 allocate(data_table(index1)%time_prev_records(prev_dims(4)))
1241 call get_time_axis(id_time_prev,data_table(index1)%time_prev_records)
1244 if_next4:
if (trim(nextfilename) /=
'')
then
1246 verbose=debug_data_override,use_comp_domain=use_comp_domain, &
1247 nwindows = nwindows, ongrid=ongrid)
1251 if ((next_dims(1) .ne. dims(1)) .or. (next_dims(2) .ne. dims(2)) .or. &
1252 (next_dims(3) .ne. dims(3)))
then
1253 call mpp_error(fatal,
'data_override: dimensions mismatch between consecutive forcing files')
1255 allocate(data_table(index1)%time_next_records(next_dims(4)))
1256 call get_time_axis(id_time_next,data_table(index1)%time_next_records)
1261 override_array(curr_position)%dims = dims
1262 if(id_time<0)
call mpp_error(fatal,
'data_override:field not found in init_external_field 1')
1263 override_array(curr_position)%t_index = id_time
1264 override_array(curr_position)%pt_index = id_time_prev
1265 override_array(curr_position)%nt_index = id_time_next
1268 axis_sizes=axis_sizes, verbose=debug_data_override,override=.true.,use_comp_domain=use_comp_domain, &
1269 nwindows = nwindows)
1273 if_multi5:
if (multifile)
then
1275 if_prev5:
if (trim(prevfilename) /=
'')
then
1276 id_time_prev =
init_external_field(prevfilename,fieldname,domain=domain, axis_names=axis_names,&
1277 axis_sizes=axis_sizes, verbose=debug_data_override,override=.true.,use_comp_domain=use_comp_domain, &
1278 nwindows = nwindows)
1280 allocate(data_table(index1)%time_prev_records(prev_dims(4)))
1281 call get_time_axis(id_time_prev,data_table(index1)%time_prev_records)
1284 if_next5:
if (trim(nextfilename) /=
'')
then
1285 id_time_next =
init_external_field(nextfilename,fieldname,domain=domain, axis_names=axis_names,&
1286 axis_sizes=axis_sizes, verbose=debug_data_override,override=.true.,use_comp_domain=use_comp_domain, &
1287 nwindows = nwindows)
1289 allocate(data_table(index1)%time_next_records(next_dims(4)))
1290 call get_time_axis(id_time_next,data_table(index1)%time_next_records)
1295 override_array(curr_position)%dims = dims
1296 if(id_time<0)
call mpp_error(fatal,
'data_override:field not found in init_external_field 2')
1297 override_array(curr_position)%t_index = id_time
1298 override_array(curr_position)%pt_index = id_time_prev
1299 override_array(curr_position)%nt_index = id_time_next
1304 allocate(override_array(curr_position)%horz_interp(nwindows))
1305 allocate(override_array(curr_position)%lon_in(axis_sizes(1)+1))
1306 allocate(override_array(curr_position)%lat_in(axis_sizes(2)+1))
1307 if(get_external_fileobj(filename, fileobj))
then
1308 call axis_edges(fileobj, axis_names(1), override_array(curr_position)%lon_in, &
1309 reproduce_null_char_bug_flag=reproduce_null_char_bug)
1310 call axis_edges(fileobj, axis_names(2), override_array(curr_position)%lat_in, &
1311 reproduce_null_char_bug_flag=reproduce_null_char_bug)
1313 call mpp_error(fatal,
'data_override: file '//trim(filename)//
' is not opened in time_interp_external')
1316 override_array(curr_position)%lon_in = override_array(curr_position)%lon_in * real(deg_to_rad, lkind)
1317 override_array(curr_position)%lat_in = override_array(curr_position)%lat_in * real(deg_to_rad, lkind)
1323 select case(gridname)
1325 lon_local => lon_local_ocn; lat_local => lat_local_ocn
1327 lon_local => lon_local_ice; lat_local => lat_local_ice
1329 lon_local => lon_local_atm; lat_local => lat_local_atm
1331 lon_local => lon_local_lnd; lat_local => lat_local_lnd
1333 call mpp_error(fatal,
'error: gridname not recognized in data_override')
1336 lat_min = minval(lat_local)
1337 lat_max = maxval(lat_local)
1339 ie_src = axis_sizes(1)
1341 je_src = axis_sizes(2)
1354 select case (data_table(index1)%interpol_method)
1356 js_src = max(1, js_src-1)
1357 je_src = min(axis_sizes(2), je_src+1)
1359 js_src = max(1, js_src-2)
1360 je_src = min(axis_sizes(2), je_src+2)
1362 override_array(curr_position)%is_src = is_src
1363 override_array(curr_position)%ie_src = ie_src
1364 override_array(curr_position)%js_src = js_src
1365 override_array(curr_position)%je_src = je_src
1368 if (trim(prevfilename) /=
'')
then
1371 if (trim(nextfilename) /=
'')
then
1377 if( data_table(index1)%region_type .NE. no_region )
then
1378 allocate( lon_tmp(axis_sizes(1)), lat_tmp(axis_sizes(2)) )
1379 call read_data(fileobj, axis_names(1), lon_tmp)
1380 call read_data(fileobj, axis_names(2), lat_tmp)
1383 if(data_table(index1)%lon_start < lon_tmp(1) .OR. data_table(index1)%lon_start .GT. lon_tmp(axis_sizes(1)))&
1384 call mpp_error(fatal,
"data_override: lon_start is outside lon_T")
1385 if( data_table(index1)%lon_end < lon_tmp(1) .OR. data_table(index1)%lon_end .GT. lon_tmp(axis_sizes(1))) &
1386 call mpp_error(fatal,
"data_override: lon_end is outside lon_T")
1387 if(data_table(index1)%lat_start < lat_tmp(1) .OR. data_table(index1)%lat_start .GT. lat_tmp(axis_sizes(2)))&
1388 call mpp_error(fatal,
"data_override: lat_start is outside lat_T")
1389 if( data_table(index1)%lat_end < lat_tmp(1) .OR. data_table(index1)%lat_end .GT. lat_tmp(axis_sizes(2))) &
1390 call mpp_error(fatal,
"data_override: lat_end is outside lat_T")
1391 istart =
nearest_index(data_table(index1)%lon_start, lon_tmp)
1393 jstart =
nearest_index(data_table(index1)%lat_start, lat_tmp)
1396 istart = istart - is_src + 1
1397 iend = iend - is_src + 1
1398 jstart = jstart - js_src + 1
1399 jend = jend - js_src + 1
1400 call set_override_region(id_time, data_table(index1)%region_type, istart, iend, jstart, jend)
1402 if (trim(prevfilename) /=
'')
then
1403 call set_override_region(id_time_prev, data_table(index1)%region_type, istart, iend, jstart, jend)
1405 if (trim(nextfilename) /=
'')
then
1406 call set_override_region(id_time_next, data_table(index1)%region_type, istart, iend, jstart, jend)
1409 deallocate(lon_tmp, lat_tmp)
1414 dims = override_array(curr_position)%dims
1415 comp_domain = override_array(curr_position)%comp_domain
1416 nxc = comp_domain(2)-comp_domain(1) + 1
1417 nyc = comp_domain(4)-comp_domain(3) + 1
1418 is_src = override_array(curr_position)%is_src
1419 ie_src = override_array(curr_position)%ie_src
1420 js_src = override_array(curr_position)%js_src
1421 je_src = override_array(curr_position)%je_src
1422 window_size = override_array(curr_position)%window_size
1424 if( window_size(1) .NE.
size(return_data,1) .OR. window_size(2) .NE.
size(return_data,2) )
then
1425 call mpp_error(fatal,
"data_override: window_size does not match size(data)")
1428 id_time = override_array(curr_position)%t_index
1429 id_time_prev = override_array(curr_position)%pt_index
1430 id_time_next = override_array(curr_position)%nt_index
1434 if( override_array(curr_position)%numwindows > 1 )
then
1435 if( .NOT.
PRESENT(is_in) .OR. .NOT.
PRESENT(is_in) .OR. .NOT.
PRESENT(is_in) .OR. .NOT.
PRESENT(is_in) )
then
1436 call mpp_error(fatal,
"data_override: is_in, ie_in, js_in, je_in must be present when nwindows > 1")
1440 isw = comp_domain(1)
1441 iew = comp_domain(2)
1442 jsw = comp_domain(3)
1443 jew = comp_domain(4)
1445 if( override_array(curr_position)%numwindows > 1 )
then
1446 nxc = comp_domain(2) - comp_domain(1) + 1
1447 nwindows_x = nxc/window_size(1)
1448 ipos = (is_in-1)/window_size(1) + 1
1449 jpos = (js_in-1)/window_size(2)
1451 window_id = jpos*nwindows_x + ipos
1452 isw = isw + is_in - 1
1453 iew = isw + ie_in - is_in
1454 jsw = jsw + js_in - 1
1455 jew = jsw + je_in - js_in
1459 need_compute = .false.
1462 need_compute=override_array(curr_position)%need_compute(window_id)
1467 if( need_compute )
then
1468 select case(gridname)
1470 lon_local => lon_local_ocn; lat_local => lat_local_ocn
1472 lon_local => lon_local_ice; lat_local => lat_local_ice
1474 lon_local => lon_local_atm; lat_local => lat_local_atm
1476 lon_local => lon_local_lnd; lat_local => lat_local_lnd
1478 call mpp_error(fatal,
'error: gridname not recognized in data_override')
1481 if (data_table(index1)%ext_weights)
then
1482 found_weight_file = .false.
1483 do i = 1, nweight_files
1484 if (external_weights(i)%weight_filename .eq. trim(data_table(index1)%ext_weights_file_name))
then
1485 override_array(curr_position)%horz_interp(window_id) = external_weights(i)%horiz_interp
1486 found_weight_file = .true.
1491 if (.not. found_weight_file)
then
1492 nweight_files = nweight_files + 1
1493 external_weights(nweight_files)%weight_filename = trim(data_table(index1)%ext_weights_file_name)
1497 external_weights(nweight_files)%weight_filename, &
1498 lon_local(isw:iew,jsw:jew), lat_local(isw:iew,jsw:jew), &
1499 override_array(curr_position)%lon_in(is_src:ie_src+1), &
1500 override_array(curr_position)%lat_in(js_src:je_src+1), &
1501 data_table(index1)%ext_weights_source, &
1502 data_table(index1)%interpol_method, isw, iew, jsw, jew, nglon, nglat)
1504 override_array(curr_position)%horz_interp(window_id) = external_weights(nweight_files)%horiz_interp
1507 select case (data_table(index1)%interpol_method)
1509 call horiz_interp_new (override_array(curr_position)%horz_interp(window_id), &
1510 override_array(curr_position)%lon_in(is_src:ie_src+1), &
1511 override_array(curr_position)%lat_in(js_src:je_src+1), &
1512 lon_local(isw:iew,jsw:jew), lat_local(isw:iew,jsw:jew), interp_method=
"bilinear")
1514 call horiz_interp_new (override_array(curr_position)%horz_interp(window_id), &
1515 override_array(curr_position)%lon_in(is_src:ie_src+1), &
1516 override_array(curr_position)%lat_in(js_src:je_src+1), &
1517 lon_local(isw:iew,jsw:jew), lat_local(isw:iew,jsw:jew), interp_method=
"bicubic")
1520 override_array(curr_position)%need_compute(window_id) = .false.
1524 data_file_is_2d = .false.
1525 if((dims(3) == 1) .and. (
size(return_data,3)>1)) data_file_is_2d = .true.
1527 if(dims(3) .NE. 1 .and. (
size(return_data,3) .NE. dims(3))) &
1528 call mpp_error(fatal, .NE..NE.
"data_override: dims(3) 1 and size(return_data,3) dims(3)")
1532 if (.not.
allocated(data_table(index1)%time_records))
allocate(data_table(index1)%time_records(dims(4)))
1535 first_record = data_table(index1)%time_records(1)
1536 last_record = data_table(index1)%time_records(dims(4))
1539 if (.not. use_comp_domain)
then
1541 nhalox = (
size(return_data,1) - nxc)/2
1542 nhaloy = (
size(return_data,2) - nyc)/2
1543 startingi = lbound(return_data,1) + nhalox
1544 startingj = lbound(return_data,2) + nhaloy
1545 endingi = ubound(return_data,1) - nhalox
1546 endingj = ubound(return_data,2) - nhaloy
1550 if(data_file_is_2d)
then
1551 if (use_comp_domain)
then
1556 if_multi6:
if (multifile)
then
1557 if_time6:
if (time<first_record)
then
1560 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1562 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1563 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1566 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1567 elseif (time>last_record)
then
1570 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1571 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1572 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1575 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1578 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1582 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1592 if_multi7:
if (multifile)
then
1593 if_time7:
if (time<first_record)
then
1596 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1598 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1599 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1602 return_data(startingi:endingi,startingj:endingj,1), &
1603 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1604 js_in=js_in,je_in=je_in,window_id=window_id)
1605 elseif (time>last_record)
then
1608 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1609 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1610 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1613 return_data(startingi:endingi,startingj:endingj,1), &
1614 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1615 js_in=js_in,je_in=je_in,window_id=window_id)
1618 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1619 js_in=js_in,je_in=je_in,window_id=window_id)
1623 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1624 js_in=js_in,je_in=je_in,window_id=window_id)
1628 return_data(:,:,1) = return_data(:,:,1)*factor
1629 do i = 2,
size(return_data,3)
1630 return_data(:,:,i) = return_data(:,:,1)
1633 if (use_comp_domain)
then
1638 if_multi8:
if (multifile)
then
1639 if_time8:
if (time<first_record)
then
1640 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1642 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1643 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1645 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1646 elseif (time>last_record)
then
1647 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1648 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1649 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1651 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1654 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1658 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1668 if_multi9:
if (multifile)
then
1669 if_time9:
if (time<first_record)
then
1670 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1672 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1673 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1675 return_data(startingi:endingi,startingj:endingj,:), &
1676 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1677 js_in=js_in,je_in=je_in,window_id=window_id)
1678 elseif (time>last_record)
then
1679 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1680 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1681 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1683 return_data(startingi:endingi,startingj:endingj,:), &
1684 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1685 js_in=js_in,je_in=je_in,window_id=window_id)
1688 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1689 js_in=js_in,je_in=je_in,window_id=window_id)
1693 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1694 js_in=js_in,je_in=je_in,window_id=window_id)
1698 return_data = return_data*factor
1702 if(data_file_is_2d)
then
1703 if( data_table(index1)%region_type == no_region )
then
1708 if_multi10:
if (multifile)
then
1709 if_time10:
if (time<first_record)
then
1710 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1712 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1713 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1715 verbose=debug_data_override, &
1716 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1717 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1718 elseif (time>last_record)
then
1719 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1720 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1721 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1723 verbose=debug_data_override, &
1724 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1725 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1728 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1729 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1733 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1734 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1737 return_data(:,:,1) = return_data(:,:,1)*factor
1738 do i = 2,
size(return_data,3)
1739 return_data(:,:,i) = return_data(:,:,1)
1742 allocate(mask_out(
size(return_data,1),
size(return_data,2),1))
1748 if_multi11:
if (multifile)
then
1749 if_time11:
if (time<first_record)
then
1750 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1752 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1753 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1755 verbose=debug_data_override, &
1756 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1757 mask_out =mask_out(:,:,1), &
1758 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1759 elseif (time>last_record)
then
1760 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1761 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1762 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1764 verbose=debug_data_override, &
1765 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1766 mask_out =mask_out(:,:,1), &
1767 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1770 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1771 mask_out =mask_out(:,:,1), &
1772 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1776 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1777 mask_out =mask_out(:,:,1), &
1778 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1781 where(mask_out(:,:,1))
1782 return_data(:,:,1) = return_data(:,:,1)*factor
1784 do i = 2,
size(return_data,3)
1785 where(mask_out(:,:,1))
1786 return_data(:,:,i) = return_data(:,:,1)
1789 deallocate(mask_out)
1792 if( data_table(index1)%region_type == no_region )
then
1797 if_multi12:
if (multifile)
then
1798 if_time12:
if (time<first_record)
then
1799 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1801 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1802 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1804 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1805 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1806 elseif (time>last_record)
then
1807 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1808 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1809 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1811 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1812 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1815 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1816 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1820 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1821 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1824 return_data = return_data*factor
1826 allocate(mask_out(
size(return_data,1),
size(return_data,2),
size(return_data,3)) )
1832 if_multi13:
if (multifile)
then
1833 if_time13:
if (time<first_record)
then
1834 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1836 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1837 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1839 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1840 mask_out =mask_out, &
1841 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1842 elseif (time>last_record)
then
1843 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1844 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1845 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1847 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1848 mask_out =mask_out, &
1849 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1852 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1853 mask_out =mask_out, &
1854 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1858 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1859 mask_out =mask_out, &
1860 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1864 return_data = return_data*factor
1866 deallocate(mask_out)
1872 if(
PRESENT(override)) override = .true.
1873 end subroutine data_override_3d_
1876 subroutine data_override_ug_1d_(gridname,fieldname,return_data,time,override)
1877 character(len=3),
intent(in) :: gridname
1878 character(len=*),
intent(in) :: fieldname
1879 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:),
intent(inout) :: return_data
1880 type(time_type),
intent(in) :: time
1881 logical,
intent(out),
optional :: override
1883 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
allocatable :: data_SG
1884 type(domainUG) :: UG_domain
1887 integer,
dimension(4) :: comp_domain = 0
1890 if(
PRESENT(override)) override = .false.
1892 do i = 1, table_size
1893 if( trim(gridname) /= trim(data_table(i)%gridname)) cycle
1894 if( trim(fieldname) /= trim(data_table(i)%fieldname_code)) cycle
1898 if(index1 .eq. -1)
return
1900 call get_domainug(gridname,ug_domain,comp_domain)
1901 allocate(data_sg(comp_domain(1):comp_domain(2),comp_domain(3):comp_domain(4)))
1903 call data_override_2d_(gridname,fieldname,data_sg,time,override)
1908 end subroutine data_override_ug_1d_
1911 subroutine data_override_ug_2d_(gridname,fieldname,return_data,time,override)
1912 character(len=3),
intent(in) :: gridname
1913 character(len=*),
intent(in) :: fieldname
1914 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
intent(inout) :: return_data
1915 type(time_type),
intent(in) :: time
1916 logical,
intent(out),
optional :: override
1918 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:,:),
allocatable :: data_SG
1919 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
allocatable :: data_UG
1920 type(domainUG) :: UG_domain
1922 integer :: i, nlevel, nlevel_max
1923 integer,
dimension(4) :: comp_domain = 0
1926 if(
PRESENT(override)) override = .false.
1928 do i = 1, table_size
1929 if( trim(gridname) /= trim(data_table(i)%gridname)) cycle
1930 if( trim(fieldname) /= trim(data_table(i)%fieldname_code)) cycle
1934 if(index1 .eq. -1)
return
1936 nlevel =
size(return_data,2)
1940 call get_domainug(gridname,ug_domain,comp_domain)
1941 allocate(data_sg(comp_domain(1):comp_domain(2),comp_domain(3):comp_domain(4),nlevel_max))
1942 allocate(data_ug(
size(return_data,1), nlevel_max))
1944 call data_override_3d_(gridname,fieldname,data_sg,time,override)
1947 return_data(:,1:nlevel) = data_ug(:,1:nlevel)
1949 deallocate(data_sg, data_ug)
1950 end subroutine data_override_ug_2d_
Perform 1D interpolation between grids.
subroutine, public fms2_io_init()
Reads the fms2_io_nml.
Close a netcdf or domain file opened with open_file or open_virtual_file.
Opens a given netcdf or domain file.
Read data from a defined field in a file.
integer function, public check_nml_error(IOSTAT, NML_NAME)
Checks the iostat argument that is returned after reading a namelist and determines if the error code...
subroutine, public write_version_number(version, tag, unit)
Prints to the log file (or a specified unit) the version id string and tag name.
character(:) function, allocatable, public string(v, fmt)
Converts a number or a Boolean value to a string.
subroutine, public horiz_interp_init
Initialize module and writes version number to logfile.out.
These routines retrieve the axis specifications associated with the compute domains....
These routines retrieve the axis specifications associated with the data domains. The domain is a der...
These routines retrieve the axis specifications associated with the global domains....
Passes data from a structured grid to an unstructured grid Example usage:
The domain2D type contains all the necessary information to define the global, compute and data domai...
Domain information for managing data on unstructured grids.
integer function stdout()
This function returns the current standard fortran unit numbers for output.
integer function stdlog()
This function returns the current standard fortran unit numbers for log messages. Log messages,...
Reduction operations. Find the max of scalar a from the PEs in pelist result is also automatically br...
integer function, dimension(4), public get_external_field_size(index)
Returns size of field after call to init_external_field. Ordering is X/Y/Z/T. This call only makes se...
subroutine, public reset_src_data_region(index, is, ie, js, je)
Reallocates src_data for field from module level loaded_fields array.
subroutine, public time_interp_external_init()
Initialize the time_interp_external_mod module.
integer function, public init_external_field(file, fieldname, domain, desired_units, verbose, axis_names, axis_sizes, override, correct_leap_year_inconsistency, permit_calendar_conversion, use_comp_domain, ierr, nwindows, ignore_axis_atts, ongrid)
Initialize an external field. Buffer "num_io_buffers" (default=2) in memory to reduce memory allocati...
subroutine, public get_time_axis(index, time)
Provide data from external file interpolated to current model time. Data may be local to current proc...
Type to represent amounts of time. Implemented as seconds and days to allow for larger intervals.
integer function, public open_and_parse_file(filename)
Opens and parses a yaml file.
subroutine, public get_block_ids(file_id, block_name, block_ids, parent_block_id)
Gets the ids of the blocks with block_name in the yaml file If parent_block_id is present,...
integer function, public get_num_blocks(file_id, block_name, parent_block_id)
Determines the number of blocks with block_name in the yaml file If parent_block_id is present,...
Dermine the value of a key from a keyname.
Allocates space and initializes a derived-type variable that contains pre-computed interpolation indi...
Subroutines for reading in weight files and using that to fill in the horiz_interp type instead calcu...