77 #include <fms_platform.h> 80 use mpp_io_mod,
only:
axistype,mpp_close,mpp_open,mpp_get_axis_data,mpp_rdonly,mpp_ascii
81 use mpp_mod,
only :
mpp_error,fatal,warning,mpp_pe,stdout,stdlog,mpp_root_pe, note,
mpp_min,
mpp_max,
mpp_chksum 104 #include<file_version.h> 107 character(len=3) :: gridname
108 character(len=128) :: fieldname_code
109 character(len=128) :: fieldname_file
110 character(len=512) :: file_name
111 character(len=128) :: interpol_method
113 real :: lon_start, lon_end, lat_start, lat_end
114 integer :: region_type
119 character(len=3) :: gridname
120 character(len=128) :: fieldname
122 type(horiz_interp_type),
pointer :: horz_interp(:) =>null()
124 integer :: comp_domain(4)
125 integer :: numthreads
126 real, _allocatable :: lon_in(:) _null
127 real, _allocatable :: lat_in(:) _null
128 logical, _allocatable :: need_compute(:) _null
129 integer :: numwindows
130 integer :: window_size(2)
131 integer :: is_src, ie_src, js_src, je_src
189 subroutine data_override_init(Atm_domain_in, Ocean_domain_in, Ice_domain_in, Land_domain_in, Land_domainUG_in)
190 type(
domain2d),
intent(in),
optional :: atm_domain_in
191 type(
domain2d),
intent(in),
optional :: ocean_domain_in, ice_domain_in
192 type(
domain2d),
intent(in),
optional :: land_domain_in
193 type(
domainug) ,
intent(in),
optional :: land_domainug_in
208 character(len=128) :: grid_file =
'INPUT/grid_spec.nc' 209 integer :: is,ie,js,je,count
210 integer :: i, iunit, ntable, ntable_lima, ntable_new, unit,io_status, ierr
211 character(len=256) :: record
214 character(len=128) :: region, region_type
221 #ifdef INTERNAL_FILE_NML 225 iunit = open_namelist_file()
226 ierr=1;
do while (ierr /= 0)
227 read (iunit, nml=data_override_nml, iostat=io_status, end=10)
230 10
call close_file (iunit)
233 write(unit, data_override_nml)
237 atm_on =
PRESENT(atm_domain_in)
238 ocn_on =
PRESENT(ocean_domain_in)
239 lnd_on =
PRESENT(land_domain_in)
240 ice_on =
PRESENT(ice_domain_in)
241 lndug_on =
PRESENT(land_domainug_in)
260 call write_version_number(
"DATA_OVERRIDE_MOD", version)
274 call mpp_open(iunit,
'data_table', action=mpp_rdonly)
280 read(iunit,
'(a)',end=100) record
281 if (record(1:1) ==
'#') cycle
282 if (record(1:10) ==
' ') cycle
284 if (index(lowercase(record),
"inside_region") .ne. 0 .or. index(lowercase(record),
"outside_region") .ne. 0)
then 285 if(index(lowercase(record),
".false.") .ne. 0 .or. index(lowercase(record),
".true.") .ne. 0 )
then 286 ntable_lima = ntable_lima + 1
287 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
288 data_entry%file_name, ongrid, data_entry%factor, region, region_type
290 data_entry%interpol_method =
'none' 292 data_entry%interpol_method =
'bilinear' 295 ntable_new=ntable_new+1
296 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
297 data_entry%file_name, data_entry%interpol_method, data_entry%factor, region, region_type
298 if (data_entry%interpol_method ==
'default')
then 301 if (.not.(data_entry%interpol_method ==
'default' .or. &
302 data_entry%interpol_method ==
'bicubic' .or. &
303 data_entry%interpol_method ==
'bilinear' .or. &
304 data_entry%interpol_method ==
'none'))
then 306 write(unit,*)
" gridname is ", trim(data_entry%gridname)
307 write(unit,*)
" fieldname_code is ", trim(data_entry%fieldname_code)
308 write(unit,*)
" fieldname_file is ", trim(data_entry%fieldname_file)
309 write(unit,*)
" file_name is ", trim(data_entry%file_name)
310 write(unit,*)
" factor is ", data_entry%factor
311 write(unit,*)
" interpol_method is ", trim(data_entry%interpol_method)
312 call mpp_error(fatal,
'data_override_mod: invalid last entry in data_override_table, ' &
313 //
'its value should be "default", "bicubic", "bilinear" or "none" ')
316 if( trim(region_type) ==
"inside_region" )
then 318 else if( trim(region_type) ==
"outside_region" )
then 321 call mpp_error(fatal,
'data_override_mod: region type should be inside_region or outside_region')
323 if (data_entry%file_name ==
"")
call mpp_error(fatal, &
324 "data_override: filename not given in data_table when region_type is not NO_REGION")
325 if(data_entry%fieldname_file ==
"")
call mpp_error(fatal, &
326 "data_override: fieldname_file must be specified in data_table when region_type is not NO_REGION")
327 if( trim(data_entry%interpol_method) ==
'none')
call mpp_error(fatal, &
328 "data_override(data_override_init): ongrid must be false when region_type is not NO_REGION")
329 read(region,*) data_entry%lon_start, data_entry%lon_end, data_entry%lat_start, data_entry%lat_end
331 if(data_entry%lon_end .LE. data_entry%lon_start)
call mpp_error(fatal, &
332 "data_override: lon_end should be greater than lon_start")
333 if(data_entry%lat_end .LE. data_entry%lat_start)
call mpp_error(fatal, &
334 "data_override: lat_end should be greater than lat_start")
335 else if (index(lowercase(record),
".false.") .ne. 0 .or. index(lowercase(record),
".true.") .ne. 0 )
then 336 ntable_lima = ntable_lima + 1
337 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
338 data_entry%file_name, ongrid, data_entry%factor
340 data_entry%interpol_method =
'none' 342 data_entry%interpol_method =
'bilinear' 344 data_entry%lon_start = 0.0
345 data_entry%lon_end = -1.0
346 data_entry%lat_start = 0.0
347 data_entry%lat_end = -1.0
350 ntable_new=ntable_new+1
351 read(record,*,err=99) data_entry%gridname, data_entry%fieldname_code, data_entry%fieldname_file, &
352 data_entry%file_name, data_entry%interpol_method, data_entry%factor
353 if (data_entry%interpol_method ==
'default')
then 356 if (.not.(data_entry%interpol_method ==
'default' .or. &
357 data_entry%interpol_method ==
'bicubic' .or. &
358 data_entry%interpol_method ==
'bilinear' .or. &
359 data_entry%interpol_method ==
'none'))
then 361 write(unit,*)
" gridname is ", trim(data_entry%gridname)
362 write(unit,*)
" fieldname_code is ", trim(data_entry%fieldname_code)
363 write(unit,*)
" fieldname_file is ", trim(data_entry%fieldname_file)
364 write(unit,*)
" file_name is ", trim(data_entry%file_name)
365 write(unit,*)
" factor is ", data_entry%factor
366 write(unit,*)
" interpol_method is ", trim(data_entry%interpol_method)
367 call mpp_error(fatal,
'data_override_mod: invalid last entry in data_override_table, ' &
368 //
'its value should be "default", "bicubic", "bilinear" or "none" ')
370 data_entry%lon_start = 0.0
371 data_entry%lon_end = -1.0
372 data_entry%lat_start = 0.0
373 data_entry%lat_end = -1.0
378 call mpp_error(fatal,
'too many enries in data_table')
379 99
call mpp_error(fatal,
'error in data_table format')
382 if(ntable_new*ntable_lima /= 0)
call mpp_error(fatal, &
383 'data_override_mod: New and old formats together in same data_table not supported')
384 call mpp_close(iunit)
403 inquire (file=trim(grid_file), opened=file_open)
404 if(file_open)
call mpp_error(fatal, trim(grid_file)//
' already opened')
436 if (
atm_on) count = count + 1
437 if (
lnd_on) count = count + 1
439 if(count .NE. 1)
call mpp_error(fatal,
'data_override_mod: the grid file is a solo mosaic, ' // &
440 'one and only one of atm_on, lnd_on or ice_on/ocn_on should be true')
470 call mpp_error(fatal,
'data_override_mod: none of x_T, geolon_t, ocn_mosaic_file or gridfiles exist in '//trim(grid_file))
486 unset_Ice, unset_Land, must_be_set)
487 logical,
intent(in),
optional :: unset_atm, unset_ocean, unset_ice, unset_land
488 logical,
intent(in),
optional :: must_be_set
493 logical :: fail_if_not_set
495 fail_if_not_set = .true. ;
if (
present(must_be_set)) fail_if_not_set = must_be_set
498 "data_override_unset_domains called with an unititialized data_override module.")
500 if (
PRESENT(unset_atm))
then ;
if (unset_atm)
then 502 "data_override_unset_domains attempted to work on an Atm_domain that had not been set.")
508 if (
PRESENT(unset_ocean))
then ;
if (unset_ocean)
then 510 "data_override_unset_domains attempted to work on an Ocn_domain that had not been set.")
516 if (
PRESENT(unset_land))
then ;
if (unset_land)
then 518 "data_override_unset_domains attempted to work on a Land_domain that had not been set.")
524 if (
PRESENT(unset_ice))
then ;
if (unset_ice)
then 526 "data_override_unset_domains attempted to work on an Ice_domain that had not been set.")
539 character(len=12),
intent(in) :: domain_name
540 type(
domain2d),
intent(in) :: domain
541 integer,
intent(in) :: nlon, nlat
543 character(len=184) :: error_message
544 integer :: xsize, ysize
547 if(nlon .NE. xsize .OR. nlat .NE. ysize)
then 548 error_message =
'Error in data_override_init. Size of grid as specified by '// &
549 ' does not conform to that specified by grid_spec.nc.'// &
550 ' From : by From grid_spec.nc: by ' 551 error_message( 59: 70) = domain_name
552 error_message(130:141) = domain_name
553 write(error_message(143:146),
'(i4)') xsize
554 write(error_message(150:153),
'(i4)') ysize
555 write(error_message(174:177),
'(i4)') nlon
556 write(error_message(181:184),
'(i4)') nlat
562 subroutine get_domain(gridname, domain, comp_domain)
564 character(len=3),
intent(in) :: gridname
565 type(domain2D),
intent(inout) :: domain
566 integer,
intent(out),
optional :: comp_domain(4)
568 domain = null_domain2d
569 select case (gridname)
579 call mpp_error(fatal,
'error in data_override get_domain')
581 if(domain .EQ. null_domain2d)
call mpp_error(fatal,
'data_override: failure in get_domain')
582 if(
present(comp_domain)) &
586 subroutine get_domainug(gridname, UGdomain, comp_domain)
588 character(len=3),
intent(in) :: gridname
589 type(domainUG),
intent(inout) :: UGdomain
590 integer,
intent(out),
optional :: comp_domain(4)
591 type(domain2D),
pointer :: SGdomain => null()
594 select case (gridname)
598 call mpp_error(fatal,
'error in data_override get_domain')
601 if(
present(comp_domain)) &
602 call mpp_get_ug_sg_domain(ugdomain,sgdomain)
611 subroutine data_override_2d(gridname,fieldname,data_2D,time,override, is_in, ie_in, js_in, je_in)
612 character(len=3),
intent(in) :: gridname
613 character(len=*),
intent(in) :: fieldname
614 logical,
intent(out),
optional :: override
615 type(time_type),
intent(in) :: time
616 real,
dimension(:,:),
intent(inout) :: data_2D
617 integer,
optional,
intent(in) :: is_in, ie_in, js_in, je_in
619 real,
dimension(:,:,:),
allocatable :: data_3D
624 if(
PRESENT(override)) override = .false.
627 if( trim(gridname) /= trim(
data_table(i)%gridname)) cycle
628 if( trim(fieldname) /= trim(
data_table(i)%fieldname_code)) cycle
632 if(index1 .eq. -1)
return 634 allocate(data_3d(
size(data_2d,1),
size(data_2d,2),1))
635 data_3d(:,:,1) = data_2d
636 call data_override_3d(gridname,fieldname,data_3d,time,override,data_index=index1,&
637 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in)
639 data_2d(:,:) = data_3d(:,:,1)
670 subroutine data_override_3d(gridname,fieldname_code,data,time,override,data_index, is_in, ie_in, js_in, je_in)
671 character(len=3),
intent(in) :: gridname
672 character(len=*),
intent(in) :: fieldname_code
673 logical,
optional,
intent(out) :: override
674 type(time_type),
intent(in) :: time
675 integer,
optional,
intent(in) :: data_index
676 real,
dimension(:,:,:),
intent(inout) :: data
677 integer,
optional,
intent(in) :: is_in, ie_in, js_in, je_in
678 logical,
dimension(:,:,:),
allocatable :: mask_out
680 character(len=512) :: filename, filename2
681 character(len=128) :: fieldname
686 integer :: axis_sizes(4)
687 real,
dimension(:,:),
pointer :: lon_local =>null(), &
689 real,
dimension(:),
allocatable :: lon_tmp, lat_tmp
691 type(axistype) :: axis_centers(4), axis_bounds(4)
692 logical :: data_file_is_2D = .false.
693 logical :: ongrid, use_comp_domain
694 type(domain2D) :: domain
695 integer :: curr_position
697 integer,
dimension(4) :: comp_domain = 0
698 integer :: nxd, nyd, nxc, nyc, nwindows
699 integer :: nwindows_x, ipos, jpos, window_size(2)
700 integer :: istart, iend, jstart, jend
701 integer :: isw, iew, jsw, jew, n
702 integer :: omp_get_num_threads, omp_get_thread_num, thread_id, window_id
703 logical :: need_compute
704 real :: lat_min, lat_max
705 integer :: is_src, ie_src, js_src, je_src
708 use_comp_domain = .false.
710 call mpp_error(fatal,
'Error: need to call data_override_init first')
713 if(
PRESENT(override)) override = .false.
714 if (
present(data_index))
then 719 if( trim(gridname) /= trim(
data_table(i)%gridname)) cycle
720 if( trim(fieldname_code) /= trim(
data_table(i)%fieldname_code)) cycle
724 if(index1 .eq. -1)
then 726 call mpp_error(warning,
'this field is NOT found in data_table: '//trim(fieldname_code))
734 if(fieldname ==
"")
then 736 if(
PRESENT(override)) override = .true.
740 if (filename ==
"")
call mpp_error(fatal,
'data_override: filename not given in data_table')
743 ongrid = (
data_table(index1)%interpol_method ==
'none')
751 if(trim(
override_array(i)%fieldname) /= trim(fieldname_code)) cycle
757 if(curr_position < 0)
then 764 nxc = comp_domain(2)-comp_domain(1) + 1
765 nyc = comp_domain(4)-comp_domain(3) + 1
783 if( nxd ==
size(
data,1) .AND. nyd ==
size(
data,2) )
then 784 use_comp_domain = .false.
785 else if ( mod(nxc,
size(
data,1)) ==0 .AND. mod(nyc,
size(
data,2)) ==0 )
then 786 use_comp_domain = .true.
787 nwindows = (nxc/
size(
data,1))*(nyc/
size(
data,2))
789 call mpp_error(fatal,
"data_override: data is not on data domain and compute domain is not divisible by size(data)")
796 if( mod(nwindows,
override_array(curr_position)%numthreads) .NE. 0 )
then 797 call mpp_error(fatal,
"data_override: nwindow is not divisible by nthreads")
805 call mpp_error(fatal,.NE.
'data_override: ongrid must be false when region_type NO_REGION')
809 inquire(file=trim(filename),exist=exists)
810 if (.not. exists)
then 817 use_comp_domain=use_comp_domain, nwindows=nwindows)
820 if(id_time<0)
call mpp_error(fatal,
'data_override:field not found in init_external_field 1')
823 id_time =
init_external_field(filename,fieldname,domain=domain, axis_centers=axis_centers,&
824 axis_sizes=axis_sizes, verbose=.false.,override=.true.,use_comp_domain=use_comp_domain, &
828 if(id_time<0)
call mpp_error(fatal,
'data_override:field not found in init_external_field 2')
839 call mpp_get_axis_data(axis_bounds(1),
override_array(curr_position)%lon_in)
840 call mpp_get_axis_data(axis_bounds(2),
override_array(curr_position)%lat_in)
850 select case(gridname)
860 call mpp_error(fatal,
'error: gridname not recognized in data_override')
863 lat_min = minval(lat_local)
864 lat_max = maxval(lat_local)
866 ie_src = axis_sizes(1)
868 je_src = axis_sizes(2)
869 do j = 1, axis_sizes(2)+1
873 do j = 1, axis_sizes(2)+1
881 select case (
data_table(index1)%interpol_method)
883 js_src =
max(1, js_src-1)
884 je_src =
min(axis_sizes(2), je_src+1)
886 js_src =
max(1, js_src-2)
887 je_src =
min(axis_sizes(2), je_src+2)
897 allocate( lon_tmp(axis_sizes(1)), lat_tmp(axis_sizes(2)) )
898 call mpp_get_axis_data(axis_centers(1), lon_tmp)
899 call mpp_get_axis_data(axis_centers(2), lat_tmp)
902 if(
data_table(index1)%lon_start < lon_tmp(1) .OR.
data_table(index1)%lon_start .GT. lon_tmp(axis_sizes(1))) &
903 call mpp_error(fatal,
"data_override: lon_start is outside lon_T")
904 if(
data_table(index1)%lon_end < lon_tmp(1) .OR.
data_table(index1)%lon_end .GT. lon_tmp(axis_sizes(1))) &
905 call mpp_error(fatal,
"data_override: lon_end is outside lon_T")
906 if(
data_table(index1)%lat_start < lat_tmp(1) .OR.
data_table(index1)%lat_start .GT. lat_tmp(axis_sizes(2))) &
907 call mpp_error(fatal,
"data_override: lat_start is outside lat_T")
908 if(
data_table(index1)%lat_end < lat_tmp(1) .OR.
data_table(index1)%lat_end .GT. lat_tmp(axis_sizes(2))) &
909 call mpp_error(fatal,
"data_override: lat_end is outside lat_T")
915 istart = istart - is_src + 1
916 iend = iend - is_src + 1
917 jstart = jstart - js_src + 1
918 jend = jend - js_src + 1
920 deallocate(lon_tmp, lat_tmp)
933 if( window_size(1) .NE.
size(
data,1) .OR. window_size(2) .NE.
size(
data,2) )
then 934 call mpp_error(fatal,
"data_override: window_size does not match size(data)")
942 if( .NOT.
PRESENT(is_in) .OR. .NOT.
PRESENT(is_in) .OR. .NOT.
PRESENT(is_in) .OR. .NOT.
PRESENT(is_in) )
then 943 call mpp_error(fatal,
"data_override: is_in, ie_in, js_in, je_in must be present when nwindows > 1")
953 nxc = comp_domain(2) - comp_domain(1) + 1
954 nwindows_x = nxc/window_size(1)
955 ipos = (is_in-1)/window_size(1) + 1
956 jpos = (js_in-1)/window_size(2)
958 window_id = jpos*nwindows_x + ipos
959 isw = isw + is_in - 1
960 iew = isw + ie_in - is_in
961 jsw = jsw + js_in - 1
962 jew = jsw + je_in - js_in
966 need_compute = .false.
969 need_compute=
override_array(curr_position)%need_compute(window_id)
974 if( need_compute )
then 975 select case(gridname)
985 call mpp_error(fatal,
'error: gridname not recognized in data_override')
988 select case (
data_table(index1)%interpol_method)
993 lon_local(isw:iew,jsw:jew), lat_local(isw:iew,jsw:jew), interp_method=
"bilinear")
998 lon_local(isw:iew,jsw:jew), lat_local(isw:iew,jsw:jew), interp_method=
"bicubic")
1004 data_file_is_2d = .false.
1005 if((dims(3) == 1) .and. (
size(
data,3)>1)) data_file_is_2d = .true.
1007 if(dims(3) .NE. 1 .and. (
size(
data,3) .NE. dims(3))) &
1008 call mpp_error(fatal, .NE..NE.
"data_override: dims(3) 1 and size(data,3) dims(3)")
1012 if(data_file_is_2d)
then 1014 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1015 data(:,:,1) =
data(:,:,1)*factor
1016 do i = 2,
size(
data,3)
1017 data(:,:,i) =
data(:,:,1)
1021 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1026 if(data_file_is_2d)
then 1029 horz_interp=
override_array(curr_position)%horz_interp(window_id), &
1030 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1031 data(:,:,1) =
data(:,:,1)*factor
1032 do i = 2,
size(
data,3)
1033 data(:,:,i) =
data(:,:,1)
1036 allocate(mask_out(
size(
data,1),
size(
data,2),1))
1039 horz_interp=
override_array(curr_position)%horz_interp(window_id), &
1040 mask_out =mask_out(:,:,1), &
1041 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1042 where(mask_out(:,:,1))
1043 data(:,:,1) =
data(:,:,1)*factor
1045 do i = 2,
size(
data,3)
1046 where(mask_out(:,:,1))
1047 data(:,:,i) =
data(:,:,1)
1050 deallocate(mask_out)
1055 horz_interp=
override_array(curr_position)%horz_interp(window_id), &
1056 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1059 allocate(mask_out(
size(
data,1),
size(
data,2),
size(
data,3)) )
1062 horz_interp=
override_array(curr_position)%horz_interp(window_id), &
1063 mask_out =mask_out, &
1064 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
1069 deallocate(mask_out)
1075 if(
PRESENT(override)) override = .true.
1104 subroutine data_override_0d(gridname,fieldname_code,data,time,override,data_index)
1105 character(len=3),
intent(in) :: gridname
1106 character(len=*),
intent(in) :: fieldname_code
1107 logical,
intent(out),
optional :: override
1108 type(time_type),
intent(in) :: time
1109 real,
intent(out) :: data
1110 integer,
intent(in),
optional :: data_index
1112 character(len=512) :: filename
1113 character(len=128) :: fieldname
1116 integer :: curr_position
1121 call mpp_error(fatal,
'Error: need to call data_override_init first')
1124 if(
PRESENT(override)) override = .false.
1125 if (
present(data_index))
then 1130 if( trim(gridname) /= trim(
data_table(i)%gridname)) cycle
1131 if( trim(fieldname_code) /= trim(
data_table(i)%fieldname_code)) cycle
1135 if(index1 .eq. -1)
then 1137 call mpp_error(warning,
'this field is NOT found in data_table: '//trim(fieldname_code))
1142 fieldname =
data_table(index1)%fieldname_file
1145 if(fieldname ==
"")
then 1147 if(
PRESENT(override)) override = .true.
1151 if (filename ==
"")
call mpp_error(fatal,
'data_override: filename not given in data_table')
1160 if(trim(
override_array(i)%fieldname) /= trim(fieldname_code)) cycle
1166 if(curr_position < 0)
then 1173 if(id_time<0)
call mpp_error(fatal,
'data_override:field not found in init_external_field 1')
1185 if(
PRESENT(override)) override = .true.
1191 character(len=3),
intent(in) :: gridname
1192 character(len=*),
intent(in) :: fieldname
1193 real,
dimension(:),
intent(inout) :: data
1194 type(time_type),
intent(in) :: time
1195 logical,
intent(out),
optional :: override
1197 real,
dimension(:,:),
allocatable :: data_SG
1198 type(domainUG) :: UG_domain
1201 integer,
dimension(4) :: comp_domain = 0
1204 if(
PRESENT(override)) override = .false.
1207 if( trim(gridname) /= trim(
data_table(i)%gridname)) cycle
1208 if( trim(fieldname) /= trim(
data_table(i)%fieldname_code)) cycle
1212 if(index1 .eq. -1)
return 1215 allocate(data_sg(comp_domain(1):comp_domain(2),comp_domain(3):comp_domain(4)))
1226 character(len=3),
intent(in) :: gridname
1227 character(len=*),
intent(in) :: fieldname
1228 real,
dimension(:,:),
intent(inout) :: data
1229 type(time_type),
intent(in) :: time
1230 logical,
intent(out),
optional :: override
1232 real,
dimension(:,:,:),
allocatable :: data_SG
1233 real,
dimension(:,:),
allocatable :: data_UG
1234 type(domainUG) :: UG_domain
1236 integer :: i, nlevel, nlevel_max
1237 integer,
dimension(4) :: comp_domain = 0
1240 if(
PRESENT(override)) override = .false.
1243 if( trim(gridname) /= trim(
data_table(i)%gridname)) cycle
1244 if( trim(fieldname) /= trim(
data_table(i)%fieldname_code)) cycle
1248 if(index1 .eq. -1)
return 1250 nlevel =
size(
data,2)
1255 allocate(data_sg(comp_domain(1):comp_domain(2),comp_domain(3):comp_domain(4),nlevel_max))
1256 allocate(data_ug(
size(
data,1), nlevel_max))
1261 data(:,1:nlevel) = data_ug(:,1:nlevel)
1263 deallocate(data_sg, data_ug)
1270 subroutine get_grid_version_1(grid_file, mod_name, domain, isc, iec, jsc, jec, lon, lat, min_lon, max_lon)
1271 character(len=*),
intent(in) :: grid_file
1272 character(len=*),
intent(in) :: mod_name
1273 type(domain2d),
intent(in) :: domain
1274 integer,
intent(in) :: isc, iec, jsc, jec
1275 real,
dimension(isc:,jsc:),
intent(out) :: lon, lat
1276 real,
intent(out) :: min_lon, max_lon
1278 integer :: i, j, siz(4)
1279 integer :: nlon, nlat
1280 real,
dimension(:,:,:),
allocatable :: lon_vert, lat_vert
1281 real,
dimension(:),
allocatable :: glon, glat
1282 logical :: is_new_grid
1283 integer :: is, ie, js, je
1284 integer :: isd, ied, jsd, jed
1285 integer :: isg, ieg, jsg, jeg
1286 type(domain2d) :: domain2
1287 character(len=3) :: xname, yname
1292 select case(mod_name)
1294 is_new_grid = .false.
1296 is_new_grid = .true.
1298 is_new_grid = .false.
1300 call mpp_error(fatal,
'data_override: both x_T and geolon_t is not in the grid file '//trim(grid_file) )
1303 if(is_new_grid)
then 1305 nlon = siz(1); nlat = siz(2)
1307 allocate(lon_vert(isc:iec,jsc:jec,4), lat_vert(isc:iec,jsc:jec,4) )
1308 call read_data(trim(grid_file),
'x_vert_T', lon_vert, domain)
1309 call read_data(trim(grid_file),
'y_vert_T', lat_vert, domain)
1312 lon(:,:) = (lon_vert(:,:,1) + lon_vert(:,:,2) + lon_vert(:,:,3) + lon_vert(:,:,4))*0.25
1313 lat(:,:) = (lat_vert(:,:,1) + lat_vert(:,:,2) + lat_vert(:,:,3) + lat_vert(:,:,4))*0.25
1316 'data_override: grid_center_bug is set to true, the grid center location may be incorrect')
1317 call field_size(grid_file,
'geolon_vert_t', siz)
1318 nlon = siz(1) - 1; nlat = siz(2) - 1;
1324 allocate(lon_vert(isc:iec+1,jsc:jec+1,1))
1325 allocate(lat_vert(isc:iec+1,jsc:jec+1,1))
1326 call read_data(trim(grid_file),
'geolon_vert_t', lon_vert, domain2)
1327 call read_data(trim(grid_file),
'geolat_vert_t', lat_vert, domain2)
1332 lon(i,j) = (lon_vert(i,j,1) + lon_vert(i+1,j,1))/2.
1333 lat(i,j) = (lat_vert(i,j,1) + lat_vert(i,j+1,1))/2.
1339 lon(i,j) = (lon_vert(i,j,1) + lon_vert(i+1,j,1) + &
1340 lon_vert(i+1,j+1,1) + lon_vert(i,j+1,1))*0.25
1341 lat(i,j) = (lat_vert(i,j,1) + lat_vert(i+1,j,1) + &
1342 lat_vert(i+1,j+1,1) + lat_vert(i,j+1,1))*0.25
1348 deallocate(lon_vert)
1349 deallocate(lat_vert)
1351 if(trim(mod_name) ==
'atm')
then 1352 xname =
'xta'; yname =
'yta' 1354 xname =
'xtl'; yname =
'ytl' 1357 nlon = siz(1);
allocate(glon(nlon))
1358 call read_data(grid_file, xname, glon, no_domain = .true.)
1361 nlat = siz(1);
allocate(glat(nlat))
1362 call read_data(grid_file, yname, glat, no_domain = .true.)
1365 is = isc - isg + 1; ie = iec - isg + 1
1366 js = jsc - jsg + 1; je = jec - jsg + 1
1376 call mpp_error(fatal,
"data_override_mod: mod_name should be 'atm', 'ocn', 'ice' or 'lnd' ")
1382 min_lon = minval(lon)
1383 max_lon = maxval(lon)
1392 subroutine get_grid_version_2(mosaic_file, mod_name, domain, isc, iec, jsc, jec, lon, lat, min_lon, max_lon)
1393 character(len=*),
intent(in) :: mosaic_file
1394 character(len=*),
intent(in) :: mod_name
1395 type(domain2d),
intent(in) :: domain
1396 integer,
intent(in) :: isc, iec, jsc, jec
1397 real,
dimension(isc:,jsc:),
intent(out) :: lon, lat
1398 real,
intent(out) :: min_lon, max_lon
1400 integer :: i, j, siz(4)
1401 integer :: nlon, nlat
1402 integer :: nlon_super, nlat_super
1403 integer :: isd, ied, jsd, jed
1404 integer :: isg, ieg, jsg, jeg
1405 integer :: isc2, iec2, jsc2, jec2
1406 character(len=256) :: solo_mosaic_file, grid_file
1407 real,
allocatable :: tmpx(:,:), tmpy(:,:)
1408 type(domain2d) :: domain2
1410 if(trim(mod_name) .NE.
'atm' .AND. trim(mod_name) .NE.
'ocn' .AND. &
1411 trim(mod_name) .NE.
'ice' .AND. trim(mod_name) .NE.
'lnd' )
call mpp_error(fatal, &
1412 "data_override_mod: mod_name should be 'atm', 'ocn', 'ice' or 'lnd' ")
1418 if(
field_exist(mosaic_file, trim(mod_name)//
'_mosaic_file' ))
then 1419 call read_data(mosaic_file, trim(mod_name)//
'_mosaic_file', solo_mosaic_file)
1420 solo_mosaic_file =
'INPUT/'//trim(solo_mosaic_file)
1422 solo_mosaic_file = mosaic_file
1427 nlon_super = siz(1); nlat_super = siz(2)
1428 if( mod(nlon_super,2) .NE. 0)
call mpp_error(fatal, &
1429 'data_override_mod: '//trim(mod_name)//
' supergrid longitude size can not be divided by 2')
1430 if( mod(nlat_super,2) .NE. 0)
call mpp_error(fatal, &
1431 'data_override_mod: '//trim(mod_name)//
' supergrid latitude size can not be divided by 2')
1432 nlon = nlon_super/2;
1433 nlat = nlat_super/2;
1439 call mpp_set_data_domain (domain2, 2*isd-1, 2*ied+1, 2*jsd-1, 2*jed+1, 2*ied-2*isd+3, 2*jed-2*jsd+3 )
1440 call mpp_set_global_domain (domain2, 2*isg-1, 2*ieg+1, 2*jsg-1, 2*jeg+1, 2*ieg-2*isg+3, 2*jeg-2*jsg+3 )
1443 if(isc2 .NE. 2*isc-1 .OR. iec2 .NE. 2*iec+1 .OR. jsc2 .NE. 2*jsc-1 .OR. jec2 .NE. 2*jec+1)
then 1444 call mpp_error(fatal,
'data_override_mod: '//trim(mod_name)//
' supergrid domain is not set properly')
1447 allocate(tmpx(isc2:iec2, jsc2:jec2), tmpy(isc2:iec2, jsc2:jec2) )
1448 call read_data( grid_file,
'x', tmpx, domain2)
1449 call read_data( grid_file,
'y', tmpy, domain2)
1451 if(trim(mod_name) ==
'ocn' .OR. trim(mod_name) ==
'ice')
then 1454 lon(i,j) = (tmpx(i*2-1,j*2-1)+tmpx(i*2+1,j*2-1)+tmpx(i*2+1,j*2+1)+tmpx(i*2-1,j*2+1))*0.25
1455 lat(i,j) = (tmpy(i*2-1,j*2-1)+tmpy(i*2+1,j*2-1)+tmpy(i*2+1,j*2+1)+tmpy(i*2-1,j*2+1))*0.25
1461 lon(i,j) = tmpx(i*2,j*2)
1462 lat(i,j) = tmpy(i*2,j*2)
1471 deallocate(tmpx, tmpy)
1472 min_lon = minval(lon)
1473 max_lon = maxval(lon)
1484 #ifdef test_data_override 1501 use mpp_mod,
only : fatal, warning, mpp_debug, note, mpp_clock_sync,mpp_clock_detailed
1502 use mpp_mod,
only : mpp_pe, mpp_npes, mpp_node, mpp_root_pe,
mpp_error, mpp_set_warn_level
1503 use mpp_mod,
only : mpp_declare_pelist, mpp_set_current_pelist, mpp_sync, mpp_sync_self
1504 use mpp_mod,
only : mpp_clock_begin, mpp_clock_end, mpp_clock_id
1508 use mpp_domains_mod,
only : global_data_domain, bitwise_exact_sum, bgrid_ne, cgrid_ne, dgrid_ne
1509 use mpp_domains_mod,
only : fold_south_edge, fold_north_edge, fold_west_edge, fold_east_edge
1510 use mpp_domains_mod,
only : mpp_domain_time, cyclic_global_domain, nupdate,eupdate, xupdate, yupdate, scalar_pair
1518 use mpp_domains_mod,
only : north, north_east, east, south_east, corner, center
1519 use mpp_domains_mod,
only : south, south_west, west, north_west, mpp_define_mosaic_pelist
1537 integer :: stdoutunit
1538 integer :: num_threads = 1
1539 integer :: omp_get_thread_num
1540 integer :: isw, iew, jsw, jew
1541 integer,
allocatable :: is_win(:), js_win(:)
1542 integer :: nx_dom, ny_dom, nx_win, ny_win
1544 integer :: nlon, nlat, siz(4)
1545 real,
allocatable,
dimension(:) :: x, y
1546 real,
allocatable,
dimension(:,:) :: lon, lat
1547 real,
allocatable,
dimension(:,:) :: sst, ice
1548 integer :: id_x, id_y, id_lon, id_lat, id_sst, id_ice
1549 integer :: i, j, is, ie, js, je, unit, io, ierr, n
1551 character(len=36) :: message
1554 logical,
allocatable :: ov_sst(:), ov_ice(:)
1555 integer,
dimension(2) :: layout = (/0,0/)
1556 character(len=256) :: solo_mosaic_file, tile_file
1557 character(len=128) :: grid_file =
"INPUT/grid_spec.nc" 1558 integer :: window(2) = (/1,1/)
1560 integer :: nthreads=1
1562 integer :: nx_cubic=0, ny_cubic=0, nx_latlon=0, ny_latlon=0
1564 namelist / test_data_override_nml / layout, window, nthreads, nx_cubic, ny_cubic, nx_latlon, ny_latlon
1569 call diag_manager_init
1571 rad_to_deg = 180./
pi 1573 #ifdef INTERNAL_FILE_NML 1574 read (input_nml_file, test_data_override_nml, iostat=io)
1575 ierr = check_nml_error(io,
'test_data_override_nml')
1577 if (file_exist(
'input.nml'))
then 1578 unit = open_namelist_file( )
1580 do while (ierr /= 0)
1581 read(unit, nml=test_data_override_nml, iostat=io, end=10)
1582 ierr = check_nml_error(io,
'test_data_override_nml')
1584 10
call close_file (unit)
1589 call field_size(grid_file,
'x_T', siz)
1592 else if(
field_exist(grid_file,
"geolon_t" ) )
then 1593 call field_size(grid_file,
'geolon_t', siz)
1596 else if (
field_exist(grid_file,
"ocn_mosaic_file" ))
then 1597 call read_data(grid_file,
'ocn_mosaic_file', solo_mosaic_file)
1598 solo_mosaic_file =
'INPUT/'//trim(solo_mosaic_file)
1599 call field_size(solo_mosaic_file,
'gridfiles', siz)
1600 if( siz(2) .NE. 1)
call error_mesg(
'test_data_override',
'only support single tile mosaic, contact developer', fatal)
1601 call read_data(solo_mosaic_file,
'gridfiles', tile_file)
1602 tile_file =
'INPUT/'//trim(tile_file)
1603 call field_size(tile_file,
'area', siz)
1604 if(mod(siz(1),2) .NE. 0 .OR. mod(siz(2),2) .NE. 0 )
call error_mesg(
'test_data_override', &
1605 "test_data_override: supergrid size can not be divided by 2", fatal)
1609 call error_mesg(
'test_data_override',
'x_T, geolon_t and ocn_mosaic_file does not exist', fatal)
1612 if(layout(1)*layout(2) .NE. mpp_npes() )
then 1617 call mpp_define_domains( (/1,nlon,1,nlat/), layout, domain, name=
'test_data_override')
1623 allocate(x(nlon), y(nlat))
1634 allocate(sst(is:ie,js:je), ice(is:ie,js:je))
1638 id_x = diag_axis_init(
'x', x,
'point_E',
'x', long_name=
'point_E', domain2=domain)
1639 id_y = diag_axis_init(
'y', y,
'point_N',
'y', long_name=
'point_N', domain2=domain)
1643 id_lon = register_static_field(
'test_data_override_mod',
'lon', (/id_x,id_y/),
'longitude',
'Degrees')
1644 id_lat = register_static_field(
'test_data_override_mod',
'lat', (/id_x,id_y/),
'longitude',
'Degrees')
1645 id_sst =
register_diag_field(
'test_data_override_mod',
'sst', (/id_x,id_y/), time,
'SST',
'K')
1646 id_ice =
register_diag_field(
'test_data_override_mod',
'ice', (/id_x,id_y/), time,
'ICE',
' ')
1655 nx_dom = ie - is + 1
1656 ny_dom = je - js + 1
1657 if( mod( nx_dom, window(1) ) .NE. 0 )
call error_mesg(
'test_data_override', &
1658 "nx_dom is not divisible by window(1)", fatal)
1659 if( mod( ny_dom, window(2) ) .NE. 0 )
call error_mesg(
'test_data_override', &
1660 "ny_dom is not divisible by window(2)", fatal)
1662 nwindows = window(1)*window(2)
1669 nx_win = nx_dom/window(1)
1670 ny_win = ny_dom/window(2)
1671 allocate(is_win(nwindows), js_win(nwindows))
1674 do jsw = js,je,ny_win
1675 do isw = is,ie,nx_win
1682 allocate(ov_sst(nwindows), ov_ice(nwindows))
1686 iew = isw + nx_win - 1
1688 jew = jsw + ny_win - 1
1689 call data_override(
'OCN',
'sst_obs',sst(isw:iew,jsw:jew),time,override=ov_sst(n), &
1690 is_in=isw-is+1, ie_in=iew-is+1, js_in=jsw-js+1, je_in=jew-js+1)
1691 call data_override(
'ICE',
'sic_obs', ice(isw:iew,jsw:jew), time, override=ov_ice(n), &
1692 is_in=isw-is+1, ie_in=iew-is+1, js_in=jsw-js+1, je_in=jew-js+1)
1695 if(any(.NOT. ov_sst) .or. any(.not.ov_ice))
then 1696 if(any(.NOT. ov_sst))
then 1697 message =
'override failed for ice' 1698 else if(any(.NOT. ov_ice))
then 1699 message =
'override failed for sst' 1701 message =
'override failed for both sst and ice' 1703 call error_mesg(
'test_data_override', trim(message), fatal)
1706 stdoutunit = stdout()
1707 write(stdoutunit,*)
"===>NOTE from test_data_override: sst chksum = ",
mpp_chksum(sst)
1708 write(stdoutunit,*)
"===>NOTE from test_data_override: ice chksum = ",
mpp_chksum(ice)
1711 if(id_sst > 0) used =
send_data(id_sst, sst, time)
1712 if(id_ice > 0) used =
send_data(id_ice, ice, time)
1714 if(nx_cubic > 0 .and. ny_cubic > 0)
then 1717 if(nx_latlon > 0 .and. ny_latlon > 0)
then 1753 call diag_manager_end(time)
1761 real,
allocatable,
dimension(:,:,:) :: lon_vert_glo, lat_vert_glo
1762 real,
allocatable,
dimension(:,:) :: lon_global, lat_global
1763 integer,
dimension(4) :: siz
1764 character(len=128) :: message
1768 call field_size(grid_file,
'x_T', siz)
1769 if(siz(1) /= nlon .or. siz(2) /= nlat)
then 1770 write(message,
'(a,2i4)')
'x_T is wrong shape. shape(x_T)=',siz(1:2)
1771 call error_mesg(
'test_data_override', trim(message), fatal)
1773 allocate(lon_vert_glo(nlon,nlat,4), lat_vert_glo(nlon,nlat,4) )
1774 allocate(lon_global(nlon,nlat ), lat_global(nlon,nlat ) )
1775 call read_data(trim(grid_file),
'x_vert_T', lon_vert_glo, no_domain=.true.)
1776 call read_data(trim(grid_file),
'y_vert_T', lat_vert_glo, no_domain=.true.)
1777 lon_global(:,:) = (lon_vert_glo(:,:,1) + lon_vert_glo(:,:,2) + lon_vert_glo(:,:,3) + lon_vert_glo(:,:,4))*0.25
1778 lat_global(:,:) = (lat_vert_glo(:,:,1) + lat_vert_glo(:,:,2) + lat_vert_glo(:,:,3) + lat_vert_glo(:,:,4))*0.25
1779 else if(
field_exist(grid_file,
"geolon_t" ) )
then 1780 call field_size(grid_file,
'geolon_vert_t', siz)
1781 if(siz(1) /= nlon+1 .or. siz(2) /= nlat+1)
then 1782 write(message,
'(a,2i4)')
'geolon_vert_t is wrong shape. shape(geolon_vert_t)=',siz(1:2)
1783 call error_mesg(
'test_data_override', trim(message), fatal)
1785 allocate(lon_vert_glo(nlon+1,nlat+1,1), lat_vert_glo(nlon+1,nlat+1,1))
1786 allocate(lon_global(nlon, nlat ), lat_global(nlon, nlat ))
1787 call read_data(trim(grid_file),
'geolon_vert_t', lon_vert_glo, no_domain=.true.)
1788 call read_data(trim(grid_file),
'geolat_vert_t', lat_vert_glo, no_domain=.true.)
1792 lon_global(i,j) = (lon_vert_glo(i,j,1) + lon_vert_glo(i+1,j,1) + &
1793 lon_vert_glo(i+1,j+1,1) + lon_vert_glo(i,j+1,1))*0.25
1794 lat_global(i,j) = (lat_vert_glo(i,j,1) + lat_vert_glo(i+1,j,1) + &
1795 lat_vert_glo(i+1,j+1,1) + lat_vert_glo(i,j+1,1))*0.25
1798 else if(
field_exist(grid_file,
"ocn_mosaic_file") )
then 1799 call field_size(tile_file,
'area', siz)
1800 if(siz(1) /= nlon*2 .or. siz(2) /= nlat*2)
then 1801 write(message,
'(a,2i4)')
'area is wrong shape. shape(area)=',siz(1:2)
1802 call error_mesg(
'test_data_override', trim(message), fatal)
1804 allocate(lon_vert_glo(siz(1)+1,siz(2)+1,1), lat_vert_glo(siz(1)+1,siz(2)+1,1))
1805 allocate(lon_global(nlon, nlat ), lat_global(nlon, nlat ))
1806 call read_data( tile_file,
'x', lon_vert_glo, no_domain=.true.)
1807 call read_data( tile_file,
'y', lat_vert_glo, no_domain=.true.)
1810 lon_global(i,j) = lon_vert_glo(i*2,j*2,1)
1811 lat_global(i,j) = lat_vert_glo(i*2,j*2,1)
1816 allocate(lon(is:ie,js:je), lat(is:ie,js:je))
1817 lon = lon_global(is:ie,js:je)
1818 lat = lat_global(is:ie,js:je)
1820 deallocate(lon_vert_glo)
1821 deallocate(lat_vert_glo)
1822 deallocate(lon_global)
1823 deallocate(lat_global)
1829 character(len=*),
intent(in) :: type
1830 type(time_type),
intent(in) :: Time
1833 integer :: nx, ny, nz=40, stackmax=4000000
1835 integer :: stdunit = 6
1836 logical :: debug=.false., opened
1839 integer :: whalo = 2, ehalo = 2, shalo = 2, nhalo = 2
1840 character(len=32) :: warn_level =
"fatal" 1841 integer :: layout_cubic(2) = (/0,0/)
1842 integer :: layout_tripolar(2) = (/0,0/)
1843 integer :: layout_ensemble(2) = (/0,0/)
1844 logical :: do_sleep = .false.
1845 integer :: num_iter = 1
1846 integer :: num_fields = 4
1848 type(domain2D) :: SG_domain
1849 type(domainUG) :: UG_domain
1850 integer :: num_contact, ntiles, npes_per_tile
1851 integer :: isc, iec, jsc, jec, isd, ied, jsd, jed
1852 integer :: ism, iem, jsm, jem, lsg, leg
1854 integer,
allocatable,
dimension(:) :: pe_start, pe_end, npts_tile, grid_index, ntiles_grid
1855 integer,
allocatable,
dimension(:,:) :: layout2D, global_indices
1856 real,
allocatable,
dimension(:,:) :: x1, x2, g1, g2
1857 real,
allocatable,
dimension(:,:,:) :: a1, a2, gdata
1858 real,
allocatable,
dimension(:,:) :: rmask
1859 real,
allocatable,
dimension(:) :: frac_crit
1860 logical,
allocatable,
dimension(:,:,:) :: lmask,msk
1861 integer,
allocatable,
dimension(:) :: isl, iel, jsl, jel
1862 character(len=3) :: text
1864 integer :: ntotal_land, istart, iend, pos
1865 integer :: outunit, errunit, k, l
1874 case (
'Cubic-Grid' )
1875 if( nx_cubic == 0 )
then 1876 call mpp_error(note,
'test_unstruct_update: for Cubic_grid mosaic, nx_cubic is zero, '//&
1877 'No test is done for Cubic-Grid mosaic. ' )
1880 if( nx_cubic .NE. ny_cubic )
then 1881 call mpp_error(note,
'test_unstruct_update: for Cubic_grid mosaic, nx_cubic does not equal ny_cubic, '//&
1882 'No test is done for Cubic-Grid mosaic. ' )
1889 if( mod(npes, ntiles) == 0 )
then 1890 npes_per_tile = npes/ntiles
1891 write(outunit,*)
'NOTE from test_unstruct_update ==> For Mosaic "', trim(type), &
1892 '", each tile will be distributed over ', npes_per_tile,
' processors.' 1894 call mpp_error(note,
'test_unstruct_update: npes should be multiple of ntiles No test is done for '//trim(type))
1897 if(layout_cubic(1)*layout_cubic(2) == npes_per_tile)
then 1898 layout = layout_cubic
1902 allocate(frac_crit(ntiles))
1903 frac_crit(1) = 0.3; frac_crit(2) = 0.1; frac_crit(3) = 0.6
1904 frac_crit(4) = 0.2; frac_crit(5) = 0.4; frac_crit(6) = 0.5
1905 allocate(layout2d(2,ntiles), global_indices(4,ntiles), pe_start(ntiles), pe_end(ntiles) )
1907 pe_start(n) = (n-1)*npes_per_tile
1908 pe_end(n) = n*npes_per_tile-1
1912 global_indices(:,n) = (/1,nx,1,ny/)
1913 layout2d(:,n) = layout
1916 call define_cubic_mosaic(
type, SG_domain, (/nx,nx,nx,nx,nx,nx/), (/ny,ny,ny,ny,ny,ny/), &
1917 global_indices, layout2D, pe_start, pe_end )
1918 case (
'Latlon-Grid' )
1919 if(nx_latlon == 0 .OR. ny_latlon == 0 )
then 1920 call mpp_error(note,
'test_unstruct_update: for latlon mosaic, nx_latlon and ny_latlon are zero, '//&
1921 'No test is done for Lalton-Grid mosaic. ' )
1927 npes_per_tile = npes
1928 allocate(frac_crit(ntiles))
1931 call mpp_define_domains((/1,nx,1,ny/), layout, sg_domain, xflags = cyclic_global_domain)
1933 call mpp_error(fatal,
'test_group_update: no such test: '//type)
1940 allocate(lmask(nx,ny,ntiles))
1941 allocate(npts_tile(ntiles))
1943 if(mpp_pe() == mpp_root_pe() )
then 1944 allocate(rmask(nx,ny))
1947 call random_number(rmask)
1950 if(rmask(i,j) > frac_crit(n))
then 1951 lmask(i,j,n) = .true.
1955 npts_tile(n) = count(lmask(:,:,n))
1957 ntotal_land = sum(npts_tile)
1958 allocate(grid_index(ntotal_land))
1960 allocate(isl(0:mpp_npes()-1), iel(0:mpp_npes()-1))
1961 allocate(jsl(0:mpp_npes()-1), jel(0:mpp_npes()-1))
1967 if(lmask(i,j,n))
then 1969 grid_index(l) = (j-1)*nx+i
1974 deallocate(rmask, isl, iel, jsl, jel)
1977 if(mpp_pe() .NE. mpp_root_pe())
then 1978 ntotal_land = sum(npts_tile)
1979 allocate(grid_index(ntotal_land))
1983 allocate(ntiles_grid(ntotal_land))
1986 call mpp_define_unstruct_domain(ug_domain, sg_domain, npts_tile, ntiles_grid, mpp_npes(), 1, grid_index, name=
"LAND unstruct")
1987 call mpp_get_ug_compute_domain(ug_domain, istart, iend)
1992 do l = 1, npts_tile(n)
1994 j = (grid_index(pos)-1)/nx + 1
1995 i = mod((grid_index(pos)-1),nx) + 1
1996 lmask(i,j,n) = .true.
2001 allocate( a1(isc:iec, jsc:jec,1), a2(isc:iec,jsc:jec,1 ) )
2002 allocate(msk(isc:iec, jsc:jec,1)); msk = .false.
2004 tile = mpp_pe()/npes_per_tile + 1
2007 msk(i,j,1) = lmask(i,j,tile)
2018 if(.NOT. msk(i,j,1)) a2(i,j,1)=a1(i,j,1)
2022 allocate(x1(istart:iend,1), x2(istart:iend,1))
2037 call compare_checksums(a1(:,:,1:1),a2(:,:,1:1),type//
' UG2SG 2-D compute domain')
2039 deallocate(a1,a2,x1,x2)
2042 allocate( a1(isc:iec, jsc:jec,nz), a2(isc:iec,jsc:jec,nz ) )
2063 if(.NOT. msk(i,j,1)) a2(i,j,k)=a1(i,j,k)
2068 allocate(x1(istart:iend,nz), x2(istart:iend,nz))
2095 deallocate(a1,a2,x1,x2)
2101 real,
intent(in),
dimension(:,:,:) :: a, b
2102 character(len=*),
intent(in) :: string
2103 integer(LONG_KIND) :: sum1, sum2
2104 integer :: i, j, k,pe
2108 call mpp_sync_self()
2111 if(
size(a,1) .ne.
size(b,1) .or.
size(a,2) .ne.
size(b,2) .or.
size(a,3) .ne.
size(b,3) ) &
2112 call mpp_error(fatal,
'compare_chksum: size of a and b does not match')
2119 if(a(i,j,k) .ne. b(i,j,k))
then 2120 print*,
"pe,i,j,k", pe,i,j,k
2121 print*,
"a =", a(i,j,k)
2122 print*,
"b =", b(i,j,k)
2125 call mpp_error(fatal, trim(
string)//
': point by point comparison are not OK.')
2134 if( sum1.EQ.sum2 )
then 2135 if( pe.EQ.mpp_root_pe() )
call mpp_error( note, trim(
string)//
': OK.' )
2146 real,
intent(in),
dimension(:,:) :: a, b
2147 character(len=*),
intent(in) :: string
2148 integer(LONG_KIND) :: sum1, sum2
2153 call mpp_sync_self()
2156 if(
size(a,1) .ne.
size(b,1) .or.
size(a,2) .ne.
size(b,2) ) &
2157 call mpp_error(fatal,
'compare_chksum_2D: size of a and b does not match')
2163 if(a(i,j) .ne. b(i,j))
then 2164 print*,
"i,j= ", i,j
2165 print*,
"a =", a(i,j)
2166 print*,
"b =", b(i,j)
2169 call mpp_error(fatal, trim(
string)//
': point by point comparison are not OK.')
2177 if( sum1.EQ.sum2 )
then 2178 if( pe.EQ.mpp_root_pe() )
call mpp_error( note, trim(
string)//
': OK.' )
2186 subroutine define_cubic_mosaic(type, domain, ni, nj, global_indices, layout, pe_start, pe_end)
2187 character(len=*),
intent(in) :: type
2188 type(domain2d),
intent(inout) :: domain
2189 integer,
intent(in) :: global_indices(:,:), layout(:,:)
2190 integer,
intent(in) :: ni(:), nj(:)
2191 integer,
intent(in) :: pe_start(:), pe_end(:)
2192 integer,
dimension(12) :: istart1, iend1, jstart1, jend1, tile1
2193 integer,
dimension(12) :: istart2, iend2, jstart2, jend2, tile2
2194 integer :: ntiles, num_contact, msize(2)
2195 integer :: whalo = 2, ehalo = 2, shalo = 2, nhalo = 2
2200 if(
size(pe_start(:)) .NE. 6 .OR.
size(pe_end(:)) .NE. 6 )
call mpp_error(fatal, &
2201 "define_cubic_mosaic: size of pe_start and pe_end should be 6")
2202 if(
size(global_indices,1) .NE. 4)
call mpp_error(fatal, &
2203 "define_cubic_mosaic: size of first dimension of global_indices should be 4")
2204 if(
size(global_indices,2) .NE. 6)
call mpp_error(fatal, &
2205 "define_cubic_mosaic: size of second dimension of global_indices should be 6")
2206 if(
size(layout,1) .NE. 2)
call mpp_error(fatal, &
2207 "define_cubic_mosaic: size of first dimension of layout should be 2")
2208 if(
size(layout,2) .NE. 6)
call mpp_error(fatal, &
2209 "define_cubic_mosaic: size of second dimension of layout should be 6")
2210 if(
size(ni(:)) .NE. 6 .OR.
size(nj(:)) .NE. 6)
call mpp_error(fatal, &
2211 "define_cubic_mosaic: size of ni and nj should be 6")
2214 tile1(1) = 1; tile2(1) = 2
2215 istart1(1) = ni(1); iend1(1) = ni(1); jstart1(1) = 1; jend1(1) = nj(1)
2216 istart2(1) = 1; iend2(1) = 1; jstart2(1) = 1; jend2(1) = nj(2)
2218 tile1(2) = 1; tile2(2) = 3
2219 istart1(2) = 1; iend1(2) = ni(1); jstart1(2) = nj(1); jend1(2) = nj(1)
2220 istart2(2) = 1; iend2(2) = 1; jstart2(2) = nj(3); jend2(2) = 1
2222 tile1(3) = 1; tile2(3) = 5
2223 istart1(3) = 1; iend1(3) = 1; jstart1(3) = 1; jend1(3) = nj(1)
2224 istart2(3) = ni(5); iend2(3) = 1; jstart2(3) = nj(5); jend2(3) = nj(5)
2226 tile1(4) = 1; tile2(4) = 6
2227 istart1(4) = 1; iend1(4) = ni(1); jstart1(4) = 1; jend1(4) = 1
2228 istart2(4) = 1; iend2(4) = ni(6); jstart2(4) = nj(6); jend2(4) = nj(6)
2230 tile1(5) = 2; tile2(5) = 3
2231 istart1(5) = 1; iend1(5) = ni(2); jstart1(5) = nj(2); jend1(5) = nj(2)
2232 istart2(5) = 1; iend2(5) = ni(3); jstart2(5) = 1; jend2(5) = 1
2234 tile1(6) = 2; tile2(6) = 4
2235 istart1(6) = ni(2); iend1(6) = ni(2); jstart1(6) = 1; jend1(6) = nj(2)
2236 istart2(6) = ni(4); iend2(6) = 1; jstart2(6) = 1; jend2(6) = 1
2238 tile1(7) = 2; tile2(7) = 6
2239 istart1(7) = 1; iend1(7) = ni(2); jstart1(7) = 1; jend1(7) = 1
2240 istart2(7) = ni(6); iend2(7) = ni(6); jstart2(7) = nj(6); jend2(7) = 1
2242 tile1(8) = 3; tile2(8) = 4
2243 istart1(8) = ni(3); iend1(8) = ni(3); jstart1(8) = 1; jend1(8) = nj(3)
2244 istart2(8) = 1; iend2(8) = 1; jstart2(8) = 1; jend2(8) = nj(4)
2246 tile1(9) = 3; tile2(9) = 5
2247 istart1(9) = 1; iend1(9) = ni(3); jstart1(9) = nj(3); jend1(9) = nj(3)
2248 istart2(9) = 1; iend2(9) = 1; jstart2(9) = nj(5); jend2(9) = 1
2250 tile1(10) = 4; tile2(10) = 5
2251 istart1(10) = 1; iend1(10) = ni(4); jstart1(10) = nj(4); jend1(10) = nj(4)
2252 istart2(10) = 1; iend2(10) = ni(5); jstart2(10) = 1; jend2(10) = 1
2254 tile1(11) = 4; tile2(11) = 6
2255 istart1(11) = ni(4); iend1(11) = ni(4); jstart1(11) = 1; jend1(11) = nj(4)
2256 istart2(11) = ni(6); iend2(11) = 1; jstart2(11) = 1; jend2(11) = 1
2258 tile1(12) = 5; tile2(12) = 6
2259 istart1(12) = ni(5); iend1(12) = ni(5); jstart1(12) = 1; jend1(12) = nj(5)
2260 istart2(12) = 1; iend2(12) = 1; jstart2(12) = 1; jend2(12) = nj(6)
2261 msize(1) = maxval(ni(:)/layout(1,:)) + whalo + ehalo + 1
2262 msize(2) = maxval(nj(:)/layout(2,:)) + shalo + nhalo + 1
2263 call mpp_define_mosaic(global_indices, layout, domain, ntiles, num_contact, tile1, tile2, &
2264 istart1, iend1, jstart1, jend1, istart2, iend2, jstart2, jend2, &
2265 pe_start, pe_end, symmetry = .true., whalo=whalo, ehalo=ehalo, &
2266 shalo=shalo, nhalo=nhalo, name = trim(type), memory_size = msize )
type(domain2d), save ocn_domain
integer, parameter annual
real, dimension(:,:), allocatable, target lon_local_lnd
integer, parameter max_array
integer, parameter, public noleap
subroutine data_override_3d(gridname, fieldname_code, data, time, override, data_index, is_in, ie_in, js_in, je_in)
subroutine define_cubic_mosaic(type, domain, ni, nj, global_indices, layout, pe_start, pe_end)
subroutine, public mpp_memuse_begin
subroutine, public data_override_init(Atm_domain_in, Ocean_domain_in, Ice_domain_in, Land_domain_in, Land_domainUG_in)
real, dimension(:,:), allocatable, target lat_local_ice
subroutine, public time_interp_external_init()
subroutine, public horiz_interp_del(Interp)
real, dimension(:,:), allocatable, target lon_local_ice
type(override_type), dimension(max_array), save override_array
integer, parameter, public inside_region
type(domain2d), save lnd_domain
subroutine compare_checksums(a, b, string)
integer function, public register_static_field(module_name, field_name, axes, long_name, units, missing_value, range, mask_variant, standard_name, DYNAMIC, do_not_log, interp_method, tile_count, area, volume, realm)
integer function, public nearest_index(value, array)
integer, parameter max_table
subroutine data_override_ug_1d(gridname, fieldname, data, time, override)
subroutine check_grid_sizes(domain_name, Domain, nlon, nlat)
subroutine, public diag_manager_end(time)
int get_cpu_affinity(void)
type(data_type) default_table
integer function, public check_nml_error(IOSTAT, NML_NAME)
real, dimension(:,:), allocatable, target lat_local_ocn
subroutine data_override_0d(gridname, fieldname_code, data, time, override, data_index)
type(override_type), save default_array
type(domainug), save lnd_domainug
subroutine get_grid_version_2(mosaic_file, mod_name, domain, isc, iec, jsc, jec, lon, lat, min_lon, max_lon)
character(len=input_str_length), dimension(:), allocatable, target, public input_nml_file
subroutine get_grid_version_1(grid_file, mod_name, domain, isc, iec, jsc, jec, lon, lat, min_lon, max_lon)
subroutine, public set_calendar_type(type, err_msg)
integer, parameter hourly
real, parameter, public pi
Ratio of circle circumference to diameter [N/A].
int field_exist(const char *file, const char *name)
subroutine, public fms_init(localcomm)
integer, parameter monthly
subroutine test_unstruct_grid(type, Time)
type(domain2d), save, public null_domain2d
real, dimension(:,:), allocatable, target lon_local_atm
integer function, public init_external_field(file, fieldname, format, threading, domain, desired_units, verbose, axis_centers, axis_sizes, override, correct_leap_year_inconsistency, permit_calendar_conversion, use_comp_domain, ierr, nwindows, ignore_axis_atts)
subroutine, public diag_manager_init(diag_model_subset, time_init, err_msg)
subroutine, public fms_io_init()
subroutine, public field_size(filename, fieldname, siz, field_found, domain, no_domain)
integer, parameter, public julian
subroutine data_override_2d(gridname, fieldname, data_2D, time, override, is_in, ie_in, js_in, je_in)
integer function, dimension(4), public get_external_field_size(index)
subroutine, public mpp_memuse_end(text, unit)
real, dimension(:,:), allocatable, target lat_local_lnd
subroutine, public horiz_interp_init
integer, parameter, public no_region
real, dimension(:,:), allocatable, target lat_local_atm
type(domainug), save, public null_domainug
subroutine, public reset_src_data_region(index, is, ie, js, je)
subroutine, public fms_end()
subroutine, public fms_io_exit()
subroutine, public set_override_region(index, region_type, is_region, ie_region, js_region, je_region)
subroutine, public get_axis_bounds(axis, axis_bound, axes, bnd_name, err_msg)
subroutine, public data_override_unset_domains(unset_Atm, unset_Ocean, unset_Ice, unset_Land, must_be_set)
subroutine, public get_mosaic_tile_grid(grid_file, mosaic_file, domain, tile_count)
subroutine compare_checksums_2d(a, b, string)
subroutine get_domainug(gridname, UGdomain, comp_domain)
type(data_type), dimension(max_table) data_table
type(domain2d), save atm_domain
real, dimension(:,:), allocatable, target lon_local_ocn
subroutine get_domain(gridname, domain, comp_domain)
logical debug_data_override
subroutine, public error_mesg(routine, message, level)
subroutine, public print_time(Time, str, unit)
type(domain2d), save ice_domain
subroutine, public constants_init
dummy routine.
subroutine data_override_ug_2d(gridname, fieldname, data, time, override)
logical module_is_initialized
integer, parameter, public outside_region