23 use platform_mod,
only: r4_kind, r8_kind, fms_path_len, fms_file_len
25 use constants_mod,
only: deg_to_rad
27 use mpp_mod,
only : input_nml_file
35 set_override_region, &
37 no_region, inside_region, outside_region, &
44 use time_manager_mod,
only:
time_type,
OPERATOR(>),
OPERATOR(<)
47 get_mosaic_tile_file, file_exists, get_instance_filename
49 use fms_string_utils_mod,
only:
string
55 #include<file_version.h>
60 character(len=3) :: gridname
61 character(len=128) :: fieldname_code
62 character(len=128) :: fieldname_file
63 character(len=FMS_PATH_LEN) :: file_name
64 character(len=128) :: interpol_method
65 logical :: ext_weights
66 character(len=128) :: ext_weights_file_name
67 character(len=128) :: ext_weights_source
68 real(FMS_DATA_OVERRIDE_KIND_) :: factor
69 real(FMS_DATA_OVERRIDE_KIND_) :: lon_start, lon_end, lat_start, lat_end
70 integer :: region_type
71 logical :: multifile = .false.
72 character(len=FMS_PATH_LEN) :: prev_file_name
73 character(len=FMS_PATH_LEN) :: next_file_name
74 type(time_type),
dimension(:),
allocatable :: time_records
75 type(time_type),
dimension(:),
allocatable :: time_prev_records
76 type(time_type),
dimension(:),
allocatable :: time_next_records
82 character(len=3) :: gridname
83 character(len=128) :: fieldname
87 type(horiz_interp_type),
allocatable :: horz_interp(:)
89 integer :: comp_domain(4)
91 real(FMS_DATA_OVERRIDE_KIND_),
allocatable :: lon_in(:)
92 real(FMS_DATA_OVERRIDE_KIND_),
allocatable :: lat_in(:)
93 logical,
allocatable :: need_compute(:)
95 integer :: window_size(2)
96 integer :: is_src, ie_src, js_src, je_src
97 end type override_type
103 type fmsexternalweights_type
104 character(len=:),
allocatable :: weight_filename
105 type(horiz_interp_type) :: horiz_interp
106 end type fmsexternalweights_type
108 integer,
parameter :: lkind = fms_data_override_kind_
109 integer,
parameter :: max_table=100, max_array=100
111 integer :: table_size
112 integer :: nweight_files
113 type(fmsExternalWeights_type),
allocatable,
target :: external_weights(:)
114 logical :: module_is_initialized = .false.
116 type(domain2D) :: ocn_domain,atm_domain,lnd_domain, ice_domain
117 type(domainUG) :: lnd_domainUG
119 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
target,
allocatable :: lon_local_ocn, lat_local_ocn
120 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
target,
allocatable :: lon_local_atm, lat_local_atm
121 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
target,
allocatable :: lon_local_ice, lat_local_ice
122 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
target,
allocatable :: lon_local_lnd, lat_local_lnd
123 real(FMS_DATA_OVERRIDE_KIND_) :: min_glo_lon_ocn, max_glo_lon_ocn
124 real(FMS_DATA_OVERRIDE_KIND_) :: min_glo_lon_atm, max_glo_lon_atm
125 real(FMS_DATA_OVERRIDE_KIND_) :: min_glo_lon_lnd, max_glo_lon_lnd
126 real(FMS_DATA_OVERRIDE_KIND_) :: min_glo_lon_ice, max_glo_lon_ice
127 integer :: num_fields = 0
129 type(data_type),
dimension(:),
allocatable :: data_table
131 type(data_type) :: default_table
132 type(override_type),
dimension(max_array) :: override_array
133 type(override_type) :: default_array
134 logical :: debug_data_override
135 logical :: grid_center_bug = .false.
136 logical :: reproduce_null_char_bug = .false.
140 logical :: use_center_grid_points=.false.
145 logical :: use_data_table_yaml = .false.
147 namelist /data_override_nml/ debug_data_override, grid_center_bug, reproduce_null_char_bug, use_data_table_yaml, &
148 use_center_grid_points
150 public :: data_override_init_impl_, data_override_unset_atm_, data_override_unset_ocn_, &
151 & data_override_unset_lnd_, data_override_unset_ice_, data_override_0d_, &
152 & data_override_2d_, data_override_3d_, data_override_ug_1d_, &
153 & data_override_ug_2d_
167 subroutine data_override_init_impl_(Atm_domain_in, Ocean_domain_in, Ice_domain_in, Land_domain_in, Land_domainUG_in)
168 type (domain2d),
intent(in),
optional :: Atm_domain_in
169 type (domain2d),
intent(in),
optional :: Ocean_domain_in
170 type (domain2d),
intent(in),
optional :: Ice_domain_in
171 type (domain2d),
intent(in),
optional :: Land_domain_in
172 type(domainUG) ,
intent(in),
optional :: Land_domainUG_in
174 character(len=18),
parameter :: grid_file =
'INPUT/grid_spec.nc'
175 integer :: i, iunit, io_status, ierr, use_get_grid_version
176 logical :: atm_on, ocn_on, lnd_on, ice_on, lndUG_on
178 type(FmsNetcdfFile_t) :: fileobj
180 debug_data_override = .false.
182 read (input_nml_file, data_override_nml, iostat=io_status)
185 write(iunit, data_override_nml)
188 if (grid_center_bug)
then
189 call mpp_error(fatal,
"data_override_init: You have overridden the default value of " // &
190 "grid_center_bug and set it to .true. in data_override_nml. This was a temporary workaround " // &
191 "that is no longer supported. Please remove this namelist variable.")
194 if (use_data_table_yaml)
then
195 call mpp_error(note,
"data_override_init: You are using the yaml version of the data table.")
197 call mpp_error(note,
"data_override_init: You are using the legacy version of the data table.")
200 atm_on =
PRESENT(atm_domain_in)
201 ocn_on =
PRESENT(ocean_domain_in)
202 lnd_on =
PRESENT(land_domain_in)
203 ice_on =
PRESENT(ice_domain_in)
204 lndug_on =
PRESENT(land_domainug_in)
205 if(.not. module_is_initialized)
then
206 atm_domain = null_domain2d
207 ocn_domain = null_domain2d
208 lnd_domain = null_domain2d
209 ice_domain = null_domain2d
210 lnd_domainug = null_domainug
212 if (atm_on) atm_domain = atm_domain_in
213 if (ocn_on) ocn_domain = ocean_domain_in
214 if (lnd_on) lnd_domain = land_domain_in
215 if (ice_on) ice_domain = ice_domain_in
216 if (lndug_on) lnd_domainug = land_domainug_in
218 if(.not. module_is_initialized)
then
223 default_table%gridname =
'non'
224 default_table%fieldname_code =
'none'
225 default_table%fieldname_file =
'none'
226 default_table%file_name =
'none'
227 default_table%factor = 1._lkind
228 default_table%interpol_method =
'bilinear'
229 default_table%multifile = .false.
230 default_table%prev_file_name =
''
231 default_table%next_file_name =
''
234 if (use_data_table_yaml)
then
235 if (file_exists(
"data_table")) &
236 call mpp_error(fatal,
"You cannot have the legacy data_table if use_data_table_yaml=.true.")
237 call read_table_yaml(data_table)
238 allocate(external_weights(table_size))
241 if (file_exists(
"data_table.yaml"))&
242 call mpp_error(fatal,
"You cannot have the yaml data_table if use_data_table_yaml=.false.")
244 &
"data_override_init:: You are using the yaml version of the data_table. &
245 The legacy data_table format will be deprecated in a future release, &
246 please switch to the yaml format.")
247 allocate(data_table(max_table))
249 data_table(i) = default_table
251 call read_table(data_table)
254 if (file_exists(
"data_table.yaml"))&
255 call mpp_error(fatal,
"You cannot have the yaml data_table if use_data_table_yaml=.false.")
257 if (use_data_table_yaml)
then
258 call mpp_error(fatal,
"You cannot have use_data_table_yaml=.true. without compiling with -Duse_yaml")
260 &
"data_override_init:: You are using the yaml version of the data_table. &
261 The legacy data_table format will be deprecated in a future release, &
262 please switch to the yaml format.")
265 allocate(data_table(max_table))
267 data_table(i) = default_table
269 call read_table(data_table)
274 default_array%gridname =
'NONE'
275 default_array%fieldname =
'NONE'
276 default_array%t_index = -1
277 default_array%dims = -1
278 default_array%comp_domain = -1
280 override_array(i) = default_array
285 module_is_initialized = .true.
287 if ( .NOT. (atm_on .or. ocn_on .or. lnd_on .or. ice_on .or. lndug_on))
return
288 if (table_size .eq. 0)
then
289 call mpp_error(note,
"data_table is empty, not doing any data_overrides")
295 inquire (file=trim(grid_file), opened=file_open)
296 if(file_open)
call mpp_error(fatal, trim(grid_file)//
' already opened')
298 if(.not.
open_file(fileobj, grid_file,
'read' ))
then
299 call mpp_error(fatal,
'data_override_mod: Error in opening file '//trim(grid_file))
302 if(variable_exists(fileobj,
"x_T" ) .OR. variable_exists(fileobj,
"geolon_t" ) )
then
303 use_get_grid_version = 1
305 else if(variable_exists(fileobj,
"ocn_mosaic_file" ) .OR. variable_exists(fileobj,
"gridfiles" ) )
then
306 use_get_grid_version = 2
307 if(variable_exists(fileobj,
"gridfiles" ) )
then
308 if(count_ne_1((ocn_on .OR. ice_on), lnd_on, atm_on))
call mpp_error(fatal,
'data_override_mod: the grid file ' //&
309 'is a solo mosaic, one and only one of atm_on, lnd_on or ice_on/ocn_on should be true')
312 call mpp_error(fatal,
'data_override_mod: none of x_T, geolon_t, ocn_mosaic_file or gridfiles exist in '// &
316 if(use_get_grid_version .EQ. 1)
then
317 if (atm_on .and. .not.
allocated(lon_local_atm) )
then
319 min_glo_lon_atm, max_glo_lon_atm )
321 if (ocn_on .and. .not.
allocated(lon_local_ocn) )
then
323 min_glo_lon_ocn, max_glo_lon_ocn )
326 if (lnd_on .and. .not.
allocated(lon_local_lnd) )
then
328 min_glo_lon_lnd, max_glo_lon_lnd )
331 if (ice_on .and. .not.
allocated(lon_local_ice) )
then
333 min_glo_lon_ice, max_glo_lon_ice )
336 if (atm_on .and. .not.
allocated(lon_local_atm) )
then
338 min_glo_lon_atm, max_glo_lon_atm )
341 if (ocn_on .and. .not.
allocated(lon_local_ocn) )
then
343 min_glo_lon_ocn, max_glo_lon_ocn, use_center_grid_points)
346 if (lnd_on .and. .not.
allocated(lon_local_lnd) )
then
348 min_glo_lon_lnd, max_glo_lon_lnd )
351 if (ice_on .and. .not.
allocated(lon_local_ice) )
then
353 min_glo_lon_ice, max_glo_lon_ice, use_center_grid_points)
356 if(use_get_grid_version .EQ. 2)
then
359 end subroutine data_override_init_impl_
373 function count_ne_1(in_1, in_2, in_3)
374 logical,
intent(in) :: in_1
375 logical,
intent(in) :: in_2
376 logical,
intent(in) :: in_3
377 logical :: count_ne_1
379 count_ne_1 = .not.(in_1.NEQV.in_2.NEQV.in_3) .OR. (in_1.AND.in_2.AND.in_3)
380 end function count_ne_1
382 subroutine read_table(data_table)
383 type(data_type),
dimension(max_table),
intent(inout) :: data_table
386 integer :: ntable_lima
387 integer :: ntable_new
391 integer :: index_1col, index_2col
392 character(len=256) :: record
393 type(data_type) :: data_entry
396 logical :: table_exists
397 character(len=128) :: region, region_type
402 inquire(file=
'data_table', exist=table_exists)
403 if (.not. table_exists)
then
404 call mpp_error(note,
'data_override_mod: File data_table does not exist.')
409 open(newunit=iunit, file=
'data_table', action=
'READ', iostat=io_status)
410 if(io_status/=0)
call mpp_error(fatal,
'data_override_mod: Error in opening file data_table.')
416 do while (ntable <= max_table)
417 read(iunit,
'(a)',
end=100) record
418 if (record(1:1) ==
'#') cycle
419 if (record(1:10) ==
' ') cycle
421 if(index(lowercase(record),
"inside_region") .ne. 0 .or. index(lowercase(record),
"outside_region") .ne. 0)
then
422 if(index(lowercase(record),
".false.") .ne. 0 .or. index(lowercase(record),
".true.") .ne. 0 )
then
423 ntable_lima = ntable_lima + 1
424 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
425 data_entry%file_name, ongrid, data_entry%factor, region, region_type
427 data_entry%interpol_method =
'none'
429 data_entry%interpol_method =
'bilinear'
432 ntable_new=ntable_new+1
433 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
434 data_entry%file_name, data_entry%interpol_method, data_entry%factor, region, &
437 if (index(data_entry%file_name,
":") .ne. 0)
then
438 data_entry%multifile = .true.
439 index_1col = index(data_entry%file_name,
":")
440 index_2col = index(data_entry%file_name(index_1col+1:),
":")
441 if (index_2col .eq. 0)
call mpp_error(fatal,
"data_override: when bridging over forcing files, " &
442 //
"central forcing files must be preceded AND followed by the column (:) separator")
443 data_entry%prev_file_name = data_entry%file_name(1:index_1col-1)
444 data_entry%next_file_name = data_entry%file_name(index_1col+index_2col+1:)
446 data_entry%file_name = data_entry%file_name(index_1col+1:index_1col+index_2col-1)
448 data_entry%multifile = .false.
449 data_entry%prev_file_name =
""
450 data_entry%next_file_name =
""
452 if (data_entry%interpol_method ==
'default')
then
453 data_entry%interpol_method = default_table%interpol_method
455 if (.not.(data_entry%interpol_method ==
'default' .or. &
456 data_entry%interpol_method ==
'bicubic' .or. &
457 data_entry%interpol_method ==
'bilinear' .or. &
458 data_entry%interpol_method ==
'none'))
then
460 write(sunit,*)
" gridname is ", trim(data_entry%gridname)
461 write(sunit,*)
" fieldname_code is ", trim(data_entry%fieldname_code)
462 write(sunit,*)
" fieldname_file is ", trim(data_entry%fieldname_file)
463 write(sunit,*)
" file_name is ", trim(data_entry%file_name)
464 write(sunit,*)
" factor is ", data_entry%factor
465 write(sunit,*)
" interpol_method is ", trim(data_entry%interpol_method)
466 call mpp_error(fatal,
'data_override_mod: invalid last entry in data_override_table, ' &
467 //
'its value should be "default", "bicubic", "bilinear" or "none" ')
470 if( trim(region_type) ==
"inside_region" )
then
471 data_entry%region_type = inside_region
472 else if( trim(region_type) ==
"outside_region" )
then
473 data_entry%region_type = outside_region
475 call mpp_error(fatal,
'data_override_mod: region type should be inside_region or outside_region')
477 if (data_entry%file_name ==
"")
call mpp_error(fatal, &
478 "data_override: filename not given in data_table when region_type is not NO_REGION")
479 if(data_entry%fieldname_file ==
"")
call mpp_error(fatal, &
480 "data_override: fieldname_file must be specified in data_table when region_type is not NO_REGION")
481 if( trim(data_entry%interpol_method) ==
'none')
call mpp_error(fatal, &
482 "data_override(data_override_init): ongrid must be false when region_type is not NO_REGION")
483 read(region,*) data_entry%lon_start, data_entry%lon_end, data_entry%lat_start, data_entry%lat_end
485 if(data_entry%lon_end .LE. data_entry%lon_start)
call mpp_error(fatal, &
486 "data_override: lon_end should be greater than lon_start")
487 if(data_entry%lat_end .LE. data_entry%lat_start)
call mpp_error(fatal, &
488 "data_override: lat_end should be greater than lat_start")
490 else if (index(lowercase(record),
".false.") .ne. 0 .or. index(lowercase(record),
".true.") .ne. 0 )
then
491 ntable_lima = ntable_lima + 1
492 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
493 data_entry%file_name, ongrid, data_entry%factor
494 if (index(data_entry%file_name,
":") .ne. 0)
then
495 data_entry%multifile = .true.
496 index_1col = index(data_entry%file_name,
":")
497 index_2col = index(data_entry%file_name(index_1col+1:),
":")
498 if (index_2col .eq. 0)
call mpp_error(fatal,
"data_override: when bridging over forcing files, " &
499 //
"central forcing files must be preceded AND followed by the column (:) separator")
500 data_entry%prev_file_name = data_entry%file_name(1:index_1col-1)
501 data_entry%next_file_name = data_entry%file_name(index_1col+index_2col+1:)
503 data_entry%file_name = data_entry%file_name(index_1col+1:index_1col+index_2col-1)
505 data_entry%multifile = .false.
506 data_entry%prev_file_name =
""
507 data_entry%next_file_name =
""
510 data_entry%interpol_method =
'none'
512 data_entry%interpol_method =
'bilinear'
514 data_entry%lon_start = 0.0_lkind
515 data_entry%lon_end = -1.0_lkind
516 data_entry%lat_start = 0.0_lkind
517 data_entry%lat_end = -1.0_lkind
518 data_entry%region_type = no_region
520 ntable_new=ntable_new+1
521 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
522 data_entry%file_name, data_entry%interpol_method, data_entry%factor
523 if (index(data_entry%file_name,
":") .ne. 0)
then
524 index_1col = index(data_entry%file_name,
":")
525 index_2col = index(data_entry%file_name(index_1col+1:),
":")
526 data_entry%multifile = .true.
527 if (index_2col .eq. 0)
call mpp_error(fatal,
"data_override: when bridging over forcing files, " &
528 //
"central forcing files must be preceded AND followed by the column (:) separator")
529 data_entry%prev_file_name = data_entry%file_name(1:index_1col-1)
530 data_entry%next_file_name = data_entry%file_name(index_1col+index_2col+1:)
532 data_entry%file_name = data_entry%file_name(index_1col+1:index_1col+index_2col-1)
534 data_entry%multifile = .false.
535 data_entry%prev_file_name =
""
536 data_entry%next_file_name =
""
538 if (data_entry%interpol_method ==
'default')
then
539 data_entry%interpol_method = default_table%interpol_method
541 if (.not.(data_entry%interpol_method ==
'default' .or. &
542 data_entry%interpol_method ==
'bicubic' .or. &
543 data_entry%interpol_method ==
'bilinear' .or. &
544 data_entry%interpol_method ==
'none'))
then
546 write(sunit,*)
" gridname is ", trim(data_entry%gridname)
547 write(sunit,*)
" fieldname_code is ", trim(data_entry%fieldname_code)
548 write(sunit,*)
" fieldname_file is ", trim(data_entry%fieldname_file)
549 write(sunit,*)
" file_name is ", trim(data_entry%file_name)
550 write(sunit,*)
" factor is ", data_entry%factor
551 write(sunit,*)
" interpol_method is ", trim(data_entry%interpol_method)
552 call mpp_error(fatal,
'data_override_mod: invalid last entry in data_override_table, ' &
553 //
'its value should be "default", "bicubic", "bilinear" or "none" ')
555 data_entry%lon_start = 0.0_lkind
556 data_entry%lon_end = -1.0_lkind
557 data_entry%lat_start = 0.0_lkind
558 data_entry%lat_end = -1.0_lkind
559 data_entry%region_type = no_region
561 data_entry%ext_weights = .false.
562 data_table(ntable) = data_entry
564 call mpp_error(fatal,
'too many enries in data_table')
565 99
call mpp_error(fatal,
'error in data_table format')
568 if(ntable_new*ntable_lima /= 0)
call mpp_error(fatal, &
569 'data_override_mod: New and old formats together in same data_table not supported')
570 close(iunit, iostat=io_status)
571 if(io_status/=0)
call mpp_error(fatal,
'data_override_mod: Error in closing file data_table')
572 end subroutine read_table
576 subroutine read_table_yaml(data_table)
577 type(data_type),
dimension(:),
allocatable,
intent(out) :: data_table
579 integer,
allocatable :: entry_id(:)
580 integer :: sub_block_id(1), sub2_block_id(1)
581 integer :: nentries, mentries
583 character(len=50) :: buffer
584 character(len=FMS_FILE_LEN) :: filename
588 call get_instance_filename(
"data_table.yaml", filename)
589 if (index(trim(filename),
"ens_") .ne. 0)
then
590 if (file_exists(filename) .and. file_exists(
"data_table.yaml")) &
591 call mpp_error(fatal,
"Both data_table.yaml and "//trim(filename)//
" exists, pick one!")
595 if (.not. file_exists(filename)) filename =
"data_table.yaml"
600 if (file_id==999)
then
604 allocate(data_table(nentries))
605 allocate(entry_id(nentries))
611 call check_for_valid_gridname(data_table(i)%gridname)
612 call get_value_from_key(file_id, entry_id(i),
"fieldname_in_model", data_table(i)%fieldname_code)
614 mentries =
get_num_blocks(file_id,
"override_file", parent_block_id=entry_id(i))
615 data_table(i)%file_name =
""
616 data_table(i)%fieldname_file =
""
617 data_table(i)%interpol_method =
"none"
618 data_table(i)%multifile = .false.
619 data_table(i)%ext_weights = .false.
620 data_table(i)%region_type = no_region
621 data_table(i)%prev_file_name =
""
622 data_table(i)%next_file_name =
""
623 data_table(i)%ext_weights_file_name =
""
624 data_table(i)%ext_weights_source =
""
627 if (mentries .eq. 0) cycle
629 if(mentries.gt.1)
call mpp_error(fatal,
"Too many override_file blocks in data table. "//&
630 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
631 trim(data_table(i)%fieldname_code))
632 call get_block_ids(file_id,
"override_file", sub_block_id, parent_block_id=entry_id(i))
634 call get_value_from_key(file_id, sub_block_id(1),
"file_name", data_table(i)%file_name)
635 call get_value_from_key(file_id, sub_block_id(1),
"fieldname_in_file", data_table(i)%fieldname_file)
636 call get_value_from_key(file_id, sub_block_id(1),
"interp_method", data_table(i)%interpol_method)
637 call check_interpol_method(data_table(i)%interpol_method, data_table(i)%file_name, &
638 & data_table(i)%fieldname_file)
640 mentries =
get_num_blocks(file_id,
"multi_file", parent_block_id=sub_block_id(1))
641 if(mentries.gt.1)
call mpp_error(fatal,
"Too many multi_file blocks in tata table. "//&
642 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
643 trim(data_table(i)%fieldname_code))
645 if(mentries.gt.0) data_table(i)%multifile = .true.
647 if (data_table(i)%multifile)
then
648 call get_block_ids(file_id,
"multi_file", sub2_block_id, parent_block_id=sub_block_id(1))
649 call get_value_from_key(file_id, sub2_block_id(1),
"prev_file_name", data_table(i)%prev_file_name)
650 call get_value_from_key(file_id, sub2_block_id(1),
"next_file_name", data_table(i)%next_file_name)
651 if (trim(data_table(i)%prev_file_name) .eq.
"" .and. trim(data_table(i)%next_file_name) .eq.
"") &
652 call mpp_error(fatal,
"The prev_file_name and next_file_name must be present if is_multi_file. "//&
653 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
654 trim(data_table(i)%fieldname_code))
657 mentries =
get_num_blocks(file_id,
"external_weights", parent_block_id=sub_block_id(1))
658 if(mentries.gt.1)
call mpp_error(fatal,
"Too many external_weight blocks in data table. "//&
659 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
660 trim(data_table(i)%fieldname_code))
662 if(mentries.gt.0) data_table(i)%ext_weights = .true.
664 if (data_table(i)%ext_weights)
then
665 call get_block_ids(file_id,
"external_weights", sub2_block_id, parent_block_id=sub_block_id(1))
666 call get_value_from_key(file_id, sub2_block_id(1),
"file_name", data_table(i)%ext_weights_file_name)
667 call get_value_from_key(file_id, sub2_block_id(1),
"source", data_table(i)%ext_weights_source)
668 if (trim(data_table(i)%ext_weights_file_name) .eq.
"" .and. trim(data_table(i)%ext_weights_source) .eq.
"") &
669 call mpp_error(fatal,
"The file_name and source must be present when using external weights"//&
670 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
671 trim(data_table(i)%fieldname_code))
674 mentries =
get_num_blocks(file_id,
"subregion", parent_block_id=entry_id(i))
675 if(mentries.gt.1)
call mpp_error(fatal,
"Too many subregion blocks in data table. "//&
676 "Check your data_table.yaml entry for field:"//trim(data_table(i)%gridname)//
":"//&
677 trim(data_table(i)%fieldname_code))
680 if(mentries.gt.0)
then
681 call get_block_ids(file_id,
"subregion", sub_block_id, parent_block_id=entry_id(i))
685 call check_and_set_region_type(buffer, data_table(i)%region_type)
686 if (data_table(i)%region_type .ne. no_region)
then
687 call get_value_from_key(file_id, sub_block_id(1),
"lon_start", data_table(i)%lon_start)
689 call get_value_from_key(file_id, sub_block_id(1),
"lat_start", data_table(i)%lat_start)
691 call check_valid_lat_lon(data_table(i)%lon_start, data_table(i)%lon_end, &
692 data_table(i)%lat_start, data_table(i)%lat_end)
697 table_size = nentries
698 end subroutine read_table_yaml
701 subroutine check_for_valid_gridname(gridname)
702 character(len=*),
intent(in) :: gridname
704 select case(trim(gridname))
705 case (
"OCN",
"ATM",
"LND",
"ICE")
707 call mpp_error(fatal, trim(gridname)//
" is not a valid gridname. "//&
708 "The acceptable values are OCN ATM LND and ICE. Check your data_table.yaml")
710 end subroutine check_for_valid_gridname
713 subroutine check_interpol_method(interp_method, filename, fieldname)
714 character(len=*),
intent(in) :: interp_method
715 character(len=*),
intent(in) :: filename
716 character(len=*),
intent(in) :: fieldname
718 select case(trim(interp_method))
719 case (
"bicubic",
"bilinear")
720 if (trim(filename) .eq.
"" .or. trim(fieldname) .eq.
"")
call mpp_error(fatal, &
721 "The file_name and the fieldname_file must be set if using the bicubic or bilinear interpolation method."//&
722 " Check your data_table.yaml")
724 if (trim(filename) .ne.
"" )
then
725 if (trim(fieldname) .eq.
"")
call mpp_error(fatal, &
726 "If the interpol_method is none and file_name is specified (ongrid case), "//&
727 "you must also specify the fieldname_file")
730 call mpp_error(fatal, trim(interp_method)//
" is not a valid interp method. "//&
731 "The acceptable values are bilinear and bicubic")
733 end subroutine check_interpol_method
737 subroutine check_and_set_region_type(region_type_str, region_type_int)
738 character(len=*),
intent(in) :: region_type_str
739 integer,
intent(out) :: region_type_int
741 select case(trim(region_type_str))
742 case (
"inside_region")
743 region_type_int = inside_region
744 case (
"outside_region")
745 region_type_int = outside_region
747 region_type_int = no_region
749 call mpp_error(fatal, trim(region_type_str)//
" is not a valid region type. "//&
750 "The acceptable values are inside_region and outside_regioon. Check your data_table.yaml")
752 end subroutine check_and_set_region_type
756 subroutine check_valid_lat_lon(lon_start, lon_end, lat_start, lat_end)
757 real(FMS_DATA_OVERRIDE_KIND_),
intent(in) :: lon_start
758 real(FMS_DATA_OVERRIDE_KIND_),
intent(in) :: lon_end
759 real(FMS_DATA_OVERRIDE_KIND_),
intent(in) :: lat_start
760 real(FMS_DATA_OVERRIDE_KIND_),
intent(in) :: lat_end
762 if (lon_start > lon_end)
call mpp_error(fatal, &
763 "lon_start:"//
string(lon_start)//
" is greater than lon_end"//
string(lon_end)//&
764 ". Check your data_table.yaml.")
766 if (lat_start > lat_end)
call mpp_error(fatal, &
767 "lat_start:"//
string(lat_start)//
" is greater than lat_end:"//
string(lat_end)//&
768 ". Check your data_table.yaml.")
769 end subroutine check_valid_lat_lon
772 subroutine data_override_unset_atm_
773 atm_domain = null_domain2d
774 if (
allocated(lon_local_atm))
deallocate(lon_local_atm)
775 if (
allocated(lat_local_atm))
deallocate(lat_local_atm)
778 subroutine data_override_unset_ocn_
779 ocn_domain = null_domain2d
780 if (
allocated(lon_local_ocn))
deallocate(lon_local_ocn)
781 if (
allocated(lat_local_ocn))
deallocate(lat_local_ocn)
784 subroutine data_override_unset_lnd_
785 lnd_domain = null_domain2d
786 if (
allocated(lon_local_lnd))
deallocate(lon_local_lnd)
787 if (
allocated(lat_local_lnd))
deallocate(lat_local_lnd)
790 subroutine data_override_unset_ice_
791 ice_domain = null_domain2d
792 if (
allocated(lon_local_ice))
deallocate(lon_local_ice)
793 if (
allocated(lat_local_ice))
deallocate(lat_local_ice)
797 subroutine get_domain(gridname, domain, comp_domain)
798 character(len=3),
intent(in) :: gridname
799 type(domain2D),
intent(inout) :: domain
800 integer,
intent(out),
optional :: comp_domain(4)
802 domain = null_domain2d
803 select case (gridname)
813 call mpp_error(fatal,
'error in data_override get_domain')
815 if(domain .EQ. null_domain2d)
call mpp_error(fatal,
'data_override: failure in get_domain')
816 if(
present(comp_domain)) &
818 end subroutine get_domain
821 subroutine get_domainug(gridname, UGdomain, comp_domain)
822 character(len=3),
intent(in) :: gridname
823 type(domainUG),
intent(inout) :: UGdomain
824 integer,
intent(out),
optional :: comp_domain(4)
825 type(domain2D),
pointer :: SGdomain => null()
827 ugdomain = null_domainug
828 select case (gridname)
830 ugdomain = lnd_domainug
832 call mpp_error(fatal,
'error in data_override get_domain')
835 if(
present(comp_domain)) &
836 call mpp_get_ug_sg_domain(ugdomain,sgdomain)
838 end subroutine get_domainug
842 subroutine data_override_0d_(gridname,fieldname_code,data_out,time,override,data_index)
843 character(len=3),
intent(in) :: gridname
844 character(len=*),
intent(in) :: fieldname_code
846 logical,
intent(out),
optional :: override
847 type(time_type),
intent(in) :: time
848 real(FMS_DATA_OVERRIDE_KIND_),
intent(out) :: data_out
849 integer,
intent(in),
optional :: data_index
851 type(time_type) :: first_record
852 type(time_type) :: last_record
853 character(len=FMS_PATH_LEN) :: filename
854 character(len=FMS_PATH_LEN) :: prevfilename
855 character(len=FMS_PATH_LEN) :: nextfilename
856 character(len=128) :: fieldname
859 integer :: prev_dims(4)
860 integer :: next_dims(4)
862 integer :: id_time_prev=-1
863 integer :: id_time_next=-1
864 integer :: curr_position
866 real(FMS_DATA_OVERRIDE_KIND_) :: factor
869 if(.not.module_is_initialized) &
870 call mpp_error(fatal,
'Error: need to call data_override_init first')
873 if(
PRESENT(override)) override = .false.
874 if (
present(data_index))
then
879 if( trim(gridname) /= trim(data_table(i)%gridname)) cycle
880 if( trim(fieldname_code) /= trim(data_table(i)%fieldname_code)) cycle
884 if(index1 .eq. -1)
then
885 if(debug_data_override) &
886 call mpp_error(warning,
'this field is NOT found in data_table: '//trim(fieldname_code))
891 fieldname = data_table(index1)%fieldname_file
892 factor = data_table(index1)%factor
893 multifile = data_table(index1)%multifile
895 if(fieldname ==
"")
then
897 if(
PRESENT(override)) override = .true.
900 filename = data_table(index1)%file_name
901 if (filename ==
"")
call mpp_error(fatal,
'data_override: filename not given in data_table')
902 if (multifile) prevfilename = data_table(index1)%prev_file_name
903 if (multifile) nextfilename = data_table(index1)%next_file_name
909 if(num_fields > 0 )
then
911 if(trim(override_array(i)%gridname) /= trim(gridname)) cycle
912 if(trim(override_array(i)%fieldname) /= trim(fieldname_code)) cycle
918 if(curr_position < 0)
then
919 num_fields = num_fields + 1
920 curr_position = num_fields
922 override_array(curr_position)%fieldname = fieldname_code
923 override_array(curr_position)%gridname = gridname
925 if(id_time<0)
call mpp_error(fatal,
'data_override:field not found in init_external_field 1')
926 override_array(curr_position)%t_index = id_time
929 id_time = override_array(curr_position)%t_index
935 if_multi1:
if (multifile)
then
937 if_prev1:
if (trim(prevfilename) /=
'')
then
942 if ((prev_dims(1) .ne. dims(1)) .or. (prev_dims(2) .ne. dims(2)) .or. &
943 (prev_dims(3) .ne. dims(3)))
then
944 call mpp_error(fatal,
'data_override: dimensions mismatch between consecutive forcing files')
946 allocate(data_table(index1)%time_prev_records(prev_dims(4)))
947 call get_time_axis(id_time_prev,data_table(index1)%time_prev_records)
950 if_next1:
if (trim(nextfilename) /=
'')
then
955 if ((next_dims(1) .ne. dims(1)) .or. (next_dims(2) .ne. dims(2)) .or. &
956 (next_dims(3) .ne. dims(3)))
then
957 call mpp_error(fatal,
'data_override: dimensions mismatch between consecutive forcing files')
959 allocate(data_table(index1)%time_next_records(next_dims(4)))
960 call get_time_axis(id_time_next,data_table(index1)%time_next_records)
970 if_multi2:
if (multifile)
then
972 if (.not.
allocated(data_table(index1)%time_records))
allocate(data_table(index1)%time_records(dims(4)))
975 first_record = data_table(index1)%time_records(1)
976 last_record = data_table(index1)%time_records(dims(4))
978 if_time2:
if (time<first_record)
then
979 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
981 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
982 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
984 elseif (time>last_record)
then
985 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
986 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
987 'data_override: time_interp_external_bridge should only be called to bridge with next file')
997 data_out = data_out*factor
1000 if(
PRESENT(override)) override = .true.
1002 end subroutine data_override_0d_
1005 subroutine data_override_2d_(gridname,fieldname,data_2D,time,override, is_in, ie_in, js_in, je_in)
1006 character(len=3),
intent(in) :: gridname
1007 character(len=*),
intent(in) :: fieldname
1008 logical,
intent(out),
optional :: override
1009 type(time_type),
intent(in) :: time
1010 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
intent(inout) :: data_2D
1011 integer,
optional,
intent(in) :: is_in, ie_in, js_in, je_in
1012 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:,:),
allocatable :: data_3D
1017 if(
PRESENT(override)) override = .false.
1019 do i = 1, table_size
1020 if( trim(gridname) /= trim(data_table(i)%gridname)) cycle
1021 if( trim(fieldname) /= trim(data_table(i)%fieldname_code)) cycle
1025 if(index1 .eq. -1)
return
1027 allocate(data_3d(
size(data_2d,1),
size(data_2d,2),1))
1028 data_3d(:,:,1) = data_2d
1029 call data_override_3d_(gridname,fieldname,data_3d,time,override,data_index=index1,&
1030 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in)
1032 data_2d(:,:) = data_3d(:,:,1)
1034 end subroutine data_override_2d_
1037 subroutine data_override_3d_(gridname,fieldname_code,return_data,time,override,data_index, is_in, ie_in, js_in, je_in)
1038 character(len=3),
intent(in) :: gridname
1039 character(len=*),
intent(in) :: fieldname_code
1040 logical,
optional,
intent(out) :: override
1041 type(time_type),
intent(in) :: time
1042 integer,
optional,
intent(in) :: data_index
1043 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:,:),
intent(inout) :: return_data
1044 integer,
optional,
intent(in) :: is_in, ie_in, js_in, je_in
1045 logical,
dimension(:,:,:),
allocatable :: mask_out
1047 character(len=FMS_PATH_LEN) :: filename
1048 character(len=FMS_PATH_LEN) :: filename2
1049 character(len=FMS_PATH_LEN) :: prevfilename
1050 character(len=FMS_PATH_LEN) :: prevfilename2
1051 character(len=FMS_PATH_LEN) :: nextfilename
1052 character(len=FMS_PATH_LEN) :: nextfilename2
1053 character(len=128) :: fieldname
1056 integer :: prev_dims(4)
1057 integer :: next_dims(4)
1060 integer :: id_time_prev=-1
1061 integer :: id_time_next=-1
1062 integer :: axis_sizes(4)
1063 character(len=32) :: axis_names(4)
1064 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
pointer :: lon_local =>null()
1065 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
pointer :: lat_local =>null()
1066 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:),
allocatable :: lon_tmp, lat_tmp
1068 logical :: data_file_is_2D = .false.
1069 logical :: ongrid, use_comp_domain
1070 type(domain2D) :: domain
1071 type(time_type) :: first_record
1072 type(time_type) :: last_record
1073 integer :: curr_position
1074 real(FMS_DATA_OVERRIDE_KIND_) :: factor
1075 integer,
dimension(4) :: comp_domain = 0
1076 integer :: nxd, nyd, nxc, nyc, nwindows
1077 integer :: nwindows_x, ipos, jpos, window_size(2)
1078 integer :: istart, iend, jstart, jend
1079 integer :: isw, iew, jsw, jew
1080 integer :: omp_get_num_threads, window_id
1081 logical :: need_compute
1082 real(FMS_DATA_OVERRIDE_KIND_) :: lat_min, lat_max
1083 integer :: is_src, ie_src, js_src, je_src
1085 logical :: multifile
1086 type(FmsNetcdfFile_t) :: fileobj
1087 integer :: startingi
1089 integer :: startingj
1093 logical :: found_weight_file
1097 use_comp_domain = .false.
1098 if(.not.module_is_initialized) &
1099 call mpp_error(fatal,
'Error: need to call data_override_init first')
1102 if(
PRESENT(override)) override = .false.
1103 if (
present(data_index))
then
1107 do i = 1, table_size
1108 if( trim(gridname) /= trim(data_table(i)%gridname)) cycle
1109 if( trim(fieldname_code) /= trim(data_table(i)%fieldname_code)) cycle
1113 if(index1 .eq. -1)
then
1114 if(debug_data_override) &
1115 call mpp_error(warning,
'this field is NOT found in data_table: '//trim(fieldname_code))
1120 fieldname = data_table(index1)%fieldname_file
1121 factor = data_table(index1)%factor
1122 multifile = data_table(index1)%multifile
1124 if(fieldname ==
"")
then
1125 return_data = factor
1126 if(
PRESENT(override)) override = .true.
1129 filename = data_table(index1)%file_name
1130 if (filename ==
"")
call mpp_error(fatal,
'data_override: filename not given in data_table')
1131 if (multifile) prevfilename = data_table(index1)%prev_file_name
1132 if (multifile) nextfilename = data_table(index1)%next_file_name
1135 ongrid = (data_table(index1)%interpol_method ==
'none')
1140 if(num_fields > 0 )
then
1141 do i = 1, num_fields
1142 if(trim(override_array(i)%gridname) /= trim(gridname)) cycle
1143 if(trim(override_array(i)%fieldname) /= trim(fieldname_code)) cycle
1149 if(curr_position < 0)
then
1150 num_fields = num_fields + 1
1151 curr_position = num_fields
1154 call get_domain(gridname,domain,comp_domain)
1156 nxc = comp_domain(2)-comp_domain(1) + 1
1157 nyc = comp_domain(4)-comp_domain(3) + 1
1160 override_array(curr_position)%fieldname = fieldname_code
1161 override_array(curr_position)%gridname = gridname
1162 override_array(curr_position)%comp_domain = comp_domain
1164 override_array(curr_position)%numthreads = 1
1165 #if defined(_OPENMP)
1166 override_array(curr_position)%numthreads = omp_get_num_threads()
1177 if( nxd ==
size(return_data,1) .AND. nyd ==
size(return_data,2) )
then
1178 use_comp_domain = .false.
1179 else if ( mod(nxc,
size(return_data,1)) ==0 .AND. mod(nyc,
size(return_data,2)) ==0 )
then
1180 use_comp_domain = .true.
1181 nwindows = (nxc/
size(return_data,1))*(nyc/
size(return_data,2))
1184 &
"data_override: data is not on data domain and compute domain is not divisible by size(data)")
1186 override_array(curr_position)%window_size(1) =
size(return_data,1)
1187 override_array(curr_position)%window_size(2) =
size(return_data,2)
1189 window_size = override_array(curr_position)%window_size
1190 override_array(curr_position)%numwindows = nwindows
1191 if( mod(nwindows, override_array(curr_position)%numthreads) .NE. 0 )
then
1192 call mpp_error(fatal,
"data_override: nwindow is not divisible by nthreads")
1194 allocate(override_array(curr_position)%need_compute(nwindows))
1195 override_array(curr_position)%need_compute = .true.
1199 if( data_table(index1)%region_type .NE. no_region )
then
1200 call mpp_error(fatal,.NE.
'data_override: ongrid must be false when region_type NO_REGION')
1204 inquire(file=trim(filename),exist=exists)
1205 if (.not. exists)
then
1206 call get_mosaic_tile_file(filename,filename2,.false.,domain)
1207 filename = filename2
1211 if_multi3:
if (multifile)
then
1212 if_prev3:
if (trim(prevfilename) /=
'')
then
1213 inquire(file=trim(prevfilename),exist=exists)
1214 if (.not. exists)
then
1215 call get_mosaic_tile_file(prevfilename,prevfilename2,.false.,domain)
1216 prevfilename = prevfilename2
1219 if_next3:
if (trim(nextfilename) /=
'')
then
1220 inquire(file=trim(nextfilename),exist=exists)
1221 if (.not. exists)
then
1222 call get_mosaic_tile_file(nextfilename,nextfilename2,.false.,domain)
1223 nextfilename = nextfilename2
1229 id_time =
init_external_field(filename,fieldname,domain=domain,verbose=debug_data_override, &
1230 use_comp_domain=use_comp_domain, nwindows=nwindows, ongrid=ongrid)
1234 if_multi4:
if (multifile)
then
1236 if_prev4:
if (trim(prevfilename) /=
'')
then
1238 verbose=debug_data_override,use_comp_domain=use_comp_domain, &
1239 nwindows = nwindows, ongrid=ongrid)
1243 if ((prev_dims(1) .ne. dims(1)) .or. (prev_dims(2) .ne. dims(2)) .or. &
1244 (prev_dims(3) .ne. dims(3)))
then
1245 call mpp_error(fatal,
'data_override: dimensions mismatch between consecutive forcing files')
1247 allocate(data_table(index1)%time_prev_records(prev_dims(4)))
1248 call get_time_axis(id_time_prev,data_table(index1)%time_prev_records)
1251 if_next4:
if (trim(nextfilename) /=
'')
then
1253 verbose=debug_data_override,use_comp_domain=use_comp_domain, &
1254 nwindows = nwindows, ongrid=ongrid)
1258 if ((next_dims(1) .ne. dims(1)) .or. (next_dims(2) .ne. dims(2)) .or. &
1259 (next_dims(3) .ne. dims(3)))
then
1260 call mpp_error(fatal,
'data_override: dimensions mismatch between consecutive forcing files')
1262 allocate(data_table(index1)%time_next_records(next_dims(4)))
1263 call get_time_axis(id_time_next,data_table(index1)%time_next_records)
1268 override_array(curr_position)%dims = dims
1269 if(id_time<0)
call mpp_error(fatal,
'data_override:field not found in init_external_field 1')
1270 override_array(curr_position)%t_index = id_time
1271 override_array(curr_position)%pt_index = id_time_prev
1272 override_array(curr_position)%nt_index = id_time_next
1275 axis_sizes=axis_sizes, verbose=debug_data_override,override=.true.,use_comp_domain=use_comp_domain, &
1276 nwindows = nwindows)
1280 if_multi5:
if (multifile)
then
1282 if_prev5:
if (trim(prevfilename) /=
'')
then
1283 id_time_prev =
init_external_field(prevfilename,fieldname,domain=domain, axis_names=axis_names,&
1284 axis_sizes=axis_sizes, verbose=debug_data_override,override=.true.,use_comp_domain=use_comp_domain, &
1285 nwindows = nwindows)
1287 allocate(data_table(index1)%time_prev_records(prev_dims(4)))
1288 call get_time_axis(id_time_prev,data_table(index1)%time_prev_records)
1291 if_next5:
if (trim(nextfilename) /=
'')
then
1292 id_time_next =
init_external_field(nextfilename,fieldname,domain=domain, axis_names=axis_names,&
1293 axis_sizes=axis_sizes, verbose=debug_data_override,override=.true.,use_comp_domain=use_comp_domain, &
1294 nwindows = nwindows)
1296 allocate(data_table(index1)%time_next_records(next_dims(4)))
1297 call get_time_axis(id_time_next,data_table(index1)%time_next_records)
1302 override_array(curr_position)%dims = dims
1303 if(id_time<0)
call mpp_error(fatal,
'data_override:field not found in init_external_field 2')
1304 override_array(curr_position)%t_index = id_time
1305 override_array(curr_position)%pt_index = id_time_prev
1306 override_array(curr_position)%nt_index = id_time_next
1311 allocate(override_array(curr_position)%horz_interp(nwindows))
1312 allocate(override_array(curr_position)%lon_in(axis_sizes(1)+1))
1313 allocate(override_array(curr_position)%lat_in(axis_sizes(2)+1))
1314 if(get_external_fileobj(filename, fileobj))
then
1315 call axis_edges(fileobj, axis_names(1), override_array(curr_position)%lon_in, &
1316 reproduce_null_char_bug_flag=reproduce_null_char_bug)
1317 call axis_edges(fileobj, axis_names(2), override_array(curr_position)%lat_in, &
1318 reproduce_null_char_bug_flag=reproduce_null_char_bug)
1320 call mpp_error(fatal,
'data_override: file '//trim(filename)//
' is not opened in time_interp_external')
1323 override_array(curr_position)%lon_in = override_array(curr_position)%lon_in * real(deg_to_rad, lkind)
1324 override_array(curr_position)%lat_in = override_array(curr_position)%lat_in * real(deg_to_rad, lkind)
1330 select case(gridname)
1332 lon_local => lon_local_ocn; lat_local => lat_local_ocn
1334 lon_local => lon_local_ice; lat_local => lat_local_ice
1336 lon_local => lon_local_atm; lat_local => lat_local_atm
1338 lon_local => lon_local_lnd; lat_local => lat_local_lnd
1340 call mpp_error(fatal,
'error: gridname not recognized in data_override')
1343 lat_min = minval(lat_local)
1344 lat_max = maxval(lat_local)
1346 ie_src = axis_sizes(1)
1348 je_src = axis_sizes(2)
1361 select case (data_table(index1)%interpol_method)
1363 js_src = max(1, js_src-1)
1364 je_src = min(axis_sizes(2), je_src+1)
1366 js_src = max(1, js_src-2)
1367 je_src = min(axis_sizes(2), je_src+2)
1369 override_array(curr_position)%is_src = is_src
1370 override_array(curr_position)%ie_src = ie_src
1371 override_array(curr_position)%js_src = js_src
1372 override_array(curr_position)%je_src = je_src
1375 if (trim(prevfilename) /=
'')
then
1378 if (trim(nextfilename) /=
'')
then
1384 if( data_table(index1)%region_type .NE. no_region )
then
1385 allocate( lon_tmp(axis_sizes(1)), lat_tmp(axis_sizes(2)) )
1386 call read_data(fileobj, axis_names(1), lon_tmp)
1387 call read_data(fileobj, axis_names(2), lat_tmp)
1390 if(data_table(index1)%lon_start < lon_tmp(1) .OR. data_table(index1)%lon_start .GT. lon_tmp(axis_sizes(1)))&
1391 call mpp_error(fatal,
"data_override: lon_start is outside lon_T")
1392 if( data_table(index1)%lon_end < lon_tmp(1) .OR. data_table(index1)%lon_end .GT. lon_tmp(axis_sizes(1))) &
1393 call mpp_error(fatal,
"data_override: lon_end is outside lon_T")
1394 if(data_table(index1)%lat_start < lat_tmp(1) .OR. data_table(index1)%lat_start .GT. lat_tmp(axis_sizes(2)))&
1395 call mpp_error(fatal,
"data_override: lat_start is outside lat_T")
1396 if( data_table(index1)%lat_end < lat_tmp(1) .OR. data_table(index1)%lat_end .GT. lat_tmp(axis_sizes(2))) &
1397 call mpp_error(fatal,
"data_override: lat_end is outside lat_T")
1398 istart =
nearest_index(data_table(index1)%lon_start, lon_tmp)
1400 jstart =
nearest_index(data_table(index1)%lat_start, lat_tmp)
1403 istart = istart - is_src + 1
1404 iend = iend - is_src + 1
1405 jstart = jstart - js_src + 1
1406 jend = jend - js_src + 1
1407 call set_override_region(id_time, data_table(index1)%region_type, istart, iend, jstart, jend)
1409 if (trim(prevfilename) /=
'')
then
1410 call set_override_region(id_time_prev, data_table(index1)%region_type, istart, iend, jstart, jend)
1412 if (trim(nextfilename) /=
'')
then
1413 call set_override_region(id_time_next, data_table(index1)%region_type, istart, iend, jstart, jend)
1416 deallocate(lon_tmp, lat_tmp)
1421 dims = override_array(curr_position)%dims
1422 comp_domain = override_array(curr_position)%comp_domain
1423 nxc = comp_domain(2)-comp_domain(1) + 1
1424 nyc = comp_domain(4)-comp_domain(3) + 1
1425 is_src = override_array(curr_position)%is_src
1426 ie_src = override_array(curr_position)%ie_src
1427 js_src = override_array(curr_position)%js_src
1428 je_src = override_array(curr_position)%je_src
1429 window_size = override_array(curr_position)%window_size
1431 if( window_size(1) .NE.
size(return_data,1) .OR. window_size(2) .NE.
size(return_data,2) )
then
1432 call mpp_error(fatal,
"data_override: window_size does not match size(data)")
1435 id_time = override_array(curr_position)%t_index
1436 id_time_prev = override_array(curr_position)%pt_index
1437 id_time_next = override_array(curr_position)%nt_index
1441 if( override_array(curr_position)%numwindows > 1 )
then
1442 if( .NOT.
PRESENT(is_in) .OR. .NOT.
PRESENT(is_in) .OR. .NOT.
PRESENT(is_in) .OR. .NOT.
PRESENT(is_in) )
then
1443 call mpp_error(fatal,
"data_override: is_in, ie_in, js_in, je_in must be present when nwindows > 1")
1447 isw = comp_domain(1)
1448 iew = comp_domain(2)
1449 jsw = comp_domain(3)
1450 jew = comp_domain(4)
1452 if( override_array(curr_position)%numwindows > 1 )
then
1453 nxc = comp_domain(2) - comp_domain(1) + 1
1454 nwindows_x = nxc/window_size(1)
1455 ipos = (is_in-1)/window_size(1) + 1
1456 jpos = (js_in-1)/window_size(2)
1458 window_id = jpos*nwindows_x + ipos
1459 isw = isw + is_in - 1
1460 iew = isw + ie_in - is_in
1461 jsw = jsw + js_in - 1
1462 jew = jsw + je_in - js_in
1466 need_compute = .false.
1469 need_compute=override_array(curr_position)%need_compute(window_id)
1474 if( need_compute )
then
1475 select case(gridname)
1477 lon_local => lon_local_ocn; lat_local => lat_local_ocn
1479 lon_local => lon_local_ice; lat_local => lat_local_ice
1481 lon_local => lon_local_atm; lat_local => lat_local_atm
1483 lon_local => lon_local_lnd; lat_local => lat_local_lnd
1485 call mpp_error(fatal,
'error: gridname not recognized in data_override')
1488 if (data_table(index1)%ext_weights)
then
1489 found_weight_file = .false.
1490 do i = 1, nweight_files
1491 if (external_weights(i)%weight_filename .eq. trim(data_table(index1)%ext_weights_file_name))
then
1492 override_array(curr_position)%horz_interp(window_id) = external_weights(i)%horiz_interp
1493 found_weight_file = .true.
1498 if (.not. found_weight_file)
then
1499 nweight_files = nweight_files + 1
1500 external_weights(nweight_files)%weight_filename = trim(data_table(index1)%ext_weights_file_name)
1504 external_weights(nweight_files)%weight_filename, &
1505 lon_local(isw:iew,jsw:jew), lat_local(isw:iew,jsw:jew), &
1506 override_array(curr_position)%lon_in(is_src:ie_src+1), &
1507 override_array(curr_position)%lat_in(js_src:je_src+1), &
1508 data_table(index1)%ext_weights_source, &
1509 data_table(index1)%interpol_method, isw, iew, jsw, jew, nglon, nglat)
1511 override_array(curr_position)%horz_interp(window_id) = external_weights(nweight_files)%horiz_interp
1514 select case (data_table(index1)%interpol_method)
1516 call horiz_interp_new (override_array(curr_position)%horz_interp(window_id), &
1517 override_array(curr_position)%lon_in(is_src:ie_src+1), &
1518 override_array(curr_position)%lat_in(js_src:je_src+1), &
1519 lon_local(isw:iew,jsw:jew), lat_local(isw:iew,jsw:jew), interp_method=
"bilinear")
1521 call horiz_interp_new (override_array(curr_position)%horz_interp(window_id), &
1522 override_array(curr_position)%lon_in(is_src:ie_src+1), &
1523 override_array(curr_position)%lat_in(js_src:je_src+1), &
1524 lon_local(isw:iew,jsw:jew), lat_local(isw:iew,jsw:jew), interp_method=
"bicubic")
1527 override_array(curr_position)%need_compute(window_id) = .false.
1531 data_file_is_2d = .false.
1532 if((dims(3) == 1) .and. (
size(return_data,3)>1)) data_file_is_2d = .true.
1534 if(dims(3) .NE. 1 .and. (
size(return_data,3) .NE. dims(3))) &
1535 call mpp_error(fatal, .NE..NE.
"data_override: dims(3) 1 and size(return_data,3) dims(3)")
1539 if (.not.
allocated(data_table(index1)%time_records))
allocate(data_table(index1)%time_records(dims(4)))
1542 first_record = data_table(index1)%time_records(1)
1543 last_record = data_table(index1)%time_records(dims(4))
1546 if (.not. use_comp_domain)
then
1548 nhalox = (
size(return_data,1) - nxc)/2
1549 nhaloy = (
size(return_data,2) - nyc)/2
1550 startingi = lbound(return_data,1) + nhalox
1551 startingj = lbound(return_data,2) + nhaloy
1552 endingi = ubound(return_data,1) - nhalox
1553 endingj = ubound(return_data,2) - nhaloy
1557 if(data_file_is_2d)
then
1558 if (use_comp_domain)
then
1563 if_multi6:
if (multifile)
then
1564 if_time6:
if (time<first_record)
then
1567 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1569 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1570 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1573 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1574 elseif (time>last_record)
then
1577 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1578 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1579 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1582 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1585 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1589 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1599 if_multi7:
if (multifile)
then
1600 if_time7:
if (time<first_record)
then
1603 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1605 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1606 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1609 return_data(startingi:endingi,startingj:endingj,1), &
1610 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1611 js_in=js_in,je_in=je_in,window_id=window_id)
1612 elseif (time>last_record)
then
1615 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1616 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1617 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1620 return_data(startingi:endingi,startingj:endingj,1), &
1621 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1622 js_in=js_in,je_in=je_in,window_id=window_id)
1625 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1626 js_in=js_in,je_in=je_in,window_id=window_id)
1630 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1631 js_in=js_in,je_in=je_in,window_id=window_id)
1635 return_data(:,:,1) = return_data(:,:,1)*factor
1636 do i = 2,
size(return_data,3)
1637 return_data(:,:,i) = return_data(:,:,1)
1640 if (use_comp_domain)
then
1645 if_multi8:
if (multifile)
then
1646 if_time8:
if (time<first_record)
then
1647 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1649 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1650 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1652 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1653 elseif (time>last_record)
then
1654 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1655 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1656 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1658 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1661 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1665 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1675 if_multi9:
if (multifile)
then
1676 if_time9:
if (time<first_record)
then
1677 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1679 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1680 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1682 return_data(startingi:endingi,startingj:endingj,:), &
1683 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1684 js_in=js_in,je_in=je_in,window_id=window_id)
1685 elseif (time>last_record)
then
1686 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1687 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1688 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1690 return_data(startingi:endingi,startingj:endingj,:), &
1691 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1692 js_in=js_in,je_in=je_in,window_id=window_id)
1695 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1696 js_in=js_in,je_in=je_in,window_id=window_id)
1700 verbose=debug_data_override,is_in=is_in,ie_in=ie_in, &
1701 js_in=js_in,je_in=je_in,window_id=window_id)
1705 return_data = return_data*factor
1709 if(data_file_is_2d)
then
1710 if( data_table(index1)%region_type == no_region )
then
1715 if_multi10:
if (multifile)
then
1716 if_time10:
if (time<first_record)
then
1717 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1719 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1720 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1722 verbose=debug_data_override, &
1723 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1724 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1725 elseif (time>last_record)
then
1726 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1727 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1728 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1730 verbose=debug_data_override, &
1731 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1732 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1735 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1736 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1740 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1741 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1744 return_data(:,:,1) = return_data(:,:,1)*factor
1745 do i = 2,
size(return_data,3)
1746 return_data(:,:,i) = return_data(:,:,1)
1749 allocate(mask_out(
size(return_data,1),
size(return_data,2),1))
1755 if_multi11:
if (multifile)
then
1756 if_time11:
if (time<first_record)
then
1757 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1759 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1760 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1762 verbose=debug_data_override, &
1763 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1764 mask_out =mask_out(:,:,1), &
1765 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1766 elseif (time>last_record)
then
1767 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1768 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1769 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1771 verbose=debug_data_override, &
1772 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1773 mask_out =mask_out(:,:,1), &
1774 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1777 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1778 mask_out =mask_out(:,:,1), &
1779 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1783 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1784 mask_out =mask_out(:,:,1), &
1785 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1788 where(mask_out(:,:,1))
1789 return_data(:,:,1) = return_data(:,:,1)*factor
1791 do i = 2,
size(return_data,3)
1792 where(mask_out(:,:,1))
1793 return_data(:,:,i) = return_data(:,:,1)
1796 deallocate(mask_out)
1799 if( data_table(index1)%region_type == no_region )
then
1804 if_multi12:
if (multifile)
then
1805 if_time12:
if (time<first_record)
then
1806 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1808 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1809 'data_override: time_interp_external_bridge should only be called to bridge with previous 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)
1813 elseif (time>last_record)
then
1814 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1815 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1816 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1818 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1819 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1822 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1823 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1827 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1828 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1831 return_data = return_data*factor
1833 allocate(mask_out(
size(return_data,1),
size(return_data,2),
size(return_data,3)) )
1839 if_multi13:
if (multifile)
then
1840 if_time13:
if (time<first_record)
then
1841 if (id_time_prev<0)
call mpp_error(fatal,
'data_override:previous file needed with multifile')
1843 if (time<data_table(index1)%time_prev_records(prev_dims(4)))
call mpp_error(fatal, &
1844 'data_override: time_interp_external_bridge should only be called to bridge with previous file')
1846 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1847 mask_out =mask_out, &
1848 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1849 elseif (time>last_record)
then
1850 if (id_time_next<0)
call mpp_error(fatal,
'data_override:next file needed with multifile')
1851 if (time>data_table(index1)%time_next_records(1))
call mpp_error(fatal, &
1852 'data_override: time_interp_external_bridge should only be called to bridge with next file')
1854 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1855 mask_out =mask_out, &
1856 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1859 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1860 mask_out =mask_out, &
1861 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1865 horz_interp=override_array(curr_position)%horz_interp(window_id), &
1866 mask_out =mask_out, &
1867 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1871 return_data = return_data*factor
1873 deallocate(mask_out)
1879 if(
PRESENT(override)) override = .true.
1880 end subroutine data_override_3d_
1883 subroutine data_override_ug_1d_(gridname,fieldname,return_data,time,override)
1884 character(len=3),
intent(in) :: gridname
1885 character(len=*),
intent(in) :: fieldname
1886 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:),
intent(inout) :: return_data
1887 type(time_type),
intent(in) :: time
1888 logical,
intent(out),
optional :: override
1890 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
allocatable :: data_SG
1891 type(domainUG) :: UG_domain
1894 integer,
dimension(4) :: comp_domain = 0
1897 if(
PRESENT(override)) override = .false.
1899 do i = 1, table_size
1900 if( trim(gridname) /= trim(data_table(i)%gridname)) cycle
1901 if( trim(fieldname) /= trim(data_table(i)%fieldname_code)) cycle
1905 if(index1 .eq. -1)
return
1907 call get_domainug(gridname,ug_domain,comp_domain)
1908 allocate(data_sg(comp_domain(1):comp_domain(2),comp_domain(3):comp_domain(4)))
1910 call data_override_2d_(gridname,fieldname,data_sg,time,override)
1915 end subroutine data_override_ug_1d_
1918 subroutine data_override_ug_2d_(gridname,fieldname,return_data,time,override)
1919 character(len=3),
intent(in) :: gridname
1920 character(len=*),
intent(in) :: fieldname
1921 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
intent(inout) :: return_data
1922 type(time_type),
intent(in) :: time
1923 logical,
intent(out),
optional :: override
1925 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:,:),
allocatable :: data_SG
1926 real(FMS_DATA_OVERRIDE_KIND_),
dimension(:,:),
allocatable :: data_UG
1927 type(domainUG) :: UG_domain
1929 integer :: i, nlevel, nlevel_max
1930 integer,
dimension(4) :: comp_domain = 0
1933 if(
PRESENT(override)) override = .false.
1935 do i = 1, table_size
1936 if( trim(gridname) /= trim(data_table(i)%gridname)) cycle
1937 if( trim(fieldname) /= trim(data_table(i)%fieldname_code)) cycle
1941 if(index1 .eq. -1)
return
1943 nlevel =
size(return_data,2)
1947 call get_domainug(gridname,ug_domain,comp_domain)
1948 allocate(data_sg(comp_domain(1):comp_domain(2),comp_domain(3):comp_domain(4),nlevel_max))
1949 allocate(data_ug(
size(return_data,1), nlevel_max))
1951 call data_override_3d_(gridname,fieldname,data_sg,time,override)
1954 return_data(:,1:nlevel) = data_ug(:,1:nlevel)
1956 deallocate(data_sg, data_ug)
1957 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...