42 private :: cnv2d_grads_bilinear
43 private :: cnv2d_grads_areaweighted
45 private :: cnv2d_write
51 real(RP),
private :: cnv2d_unittile_ddeg = 0.0_rp
52 real(RP),
private :: cnv2d_oversampling_factor = 2.0_rp
54 character(len=H_SHORT),
private :: cnv2d_interpolation_type =
'bilinear' 59 character(len=H_LONG),
private :: cnv2d_out_basename =
'' 60 character(len=H_MID),
private :: cnv2d_out_title =
'SCALE-RM 2D Boundary' 61 character(len=H_SHORT),
private :: cnv2d_out_varname =
'' 62 character(len=H_MID),
private :: cnv2d_out_vardesc =
'' 63 character(len=H_SHORT),
private :: cnv2d_out_varunit =
'' 64 character(len=H_SHORT),
private :: cnv2d_out_dtype =
'DEFAULT' 76 statistics_horizontal_min
82 namelist / param_cnv2d / &
84 cnv2d_interpolation_type, &
85 cnv2d_unittile_ddeg, &
86 cnv2d_oversampling_factor, &
94 real(RP) :: drad(
ia,
ja)
101 log_info(
"CNV2D_setup",*)
'Setup' 107 log_info(
"CNV2D_setup",*)
'Not found namelist. Default used.' 108 elseif( ierr > 0 )
then 109 log_error(
"CNV2D_setup",*)
'Not appropriate names in namelist PARAM_CNV2D. Check!' 118 log_info(
"CNV2D_setup",*)
'Use GrADS format file for input' 121 if ( cnv2d_interpolation_type ==
'bilinear' )
then 122 log_info(
"CNV2D_setup",*)
'Interpolation type : bi-linear interpolation (coarse input->fine model grid)' 123 elseif( cnv2d_interpolation_type ==
'areaweighted' )
then 124 log_info(
"CNV2D_setup",*)
'Interpolation type : area-weighted average (fine input->coarse model grid)' 125 elseif( cnv2d_interpolation_type ==
'nearestneighbor' )
then 126 log_info(
"CNV2D_setup",*)
'Interpolation type : nearest neighbor' 128 log_error(
"CNV2D_setup",*)
'Not appropriate interpolation type. Check!', trim(cnv2d_interpolation_type)
133 log_info(
"CNV2D_setup",*)
'Do nothing for 2D data conversion' 135 drad(:,:) = min( real_dlat(:,:), real_dlon(:,:) )
136 call statistics_horizontal_min(
ia,
is,
ie,
ja,
js,
je, &
137 drad(:,:), drad_min )
139 if ( cnv2d_unittile_ddeg > 0.0_rp )
then 140 cnv2d_oversampling_factor = ( drad_min / d2r ) / cnv2d_unittile_ddeg
142 cnv2d_oversampling_factor = max( 1.0_rp, cnv2d_oversampling_factor )
143 cnv2d_unittile_ddeg = ( drad_min / d2r ) / cnv2d_oversampling_factor
145 log_info(
"CNV2D_setup",*)
'The size of tile [deg] = ', cnv2d_unittile_ddeg
146 log_info(
"CNV2D_setup",*)
'oversampling factor = ', cnv2d_oversampling_factor
160 log_progress(*)
'skip convert topography data' 163 log_progress(*)
'start convert topography data' 169 log_progress(*)
'end convert topography data' 177 subroutine cnv2d_grads
191 integer :: GrADS_NLAT = -1
192 integer :: GrADS_NLON = -1
193 real(RP) :: GrADS_DLAT = -1.0_rp
194 real(RP) :: GrADS_DLON = -1.0_rp
195 character(len=H_LONG) :: GrADS_IN_DIR =
'.' 196 character(len=H_LONG) :: GrADS_IN_CATALOGUE =
'' 197 character(len=H_LONG) :: GrADS_IN_FILENAME =
'' 198 character(len=H_LONG) :: GrADS_IN_DATATYPE =
'REAL4' 199 logical :: GrADS_LATORDER_N2S = .false.
200 real(RP) :: GrADS_MISSINGVAL
201 real(RP) :: GrADS_LAT_START = -90.0_rp
202 real(RP) :: GrADS_LAT_END = 90.0_rp
203 real(RP) :: GrADS_LON_START = 0.0_rp
204 real(RP) :: GrADS_LON_END = 360.0_rp
205 integer :: GrADS_NSTEP = 1
206 real(DP) :: GrADS_DT = 0.0_dp
207 character(len=H_SHORT) :: GrADS_DT_UNIT =
"SEC" 209 namelist / param_cnv2d_grads / &
214 grads_in_catalogue, &
218 grads_latorder_n2s, &
228 real(RP) :: VAR2D(
ia,
ja)
229 real(DP) :: VAR2D_DTSEC
231 real(RP) :: REAL_LONUY_mod(0:
ia,
ja)
232 real(RP) :: DOMAIN_LATS, DOMAIN_LATE
233 real(RP) :: DOMAIN_LONS, DOMAIN_LONE
234 integer :: DOMAIN_LONSLOC(2), DOMAIN_LONELOC(2)
237 integer :: TILE_NLAT, TILE_NLON
238 real(RP) :: TILE_DLAT, TILE_DLON
241 integer,
parameter :: TILE_nlim = 1000
243 character(len=H_LONG) :: TILE_fname(tile_nlim)
244 real(RP) :: TILE_LATS (tile_nlim)
245 real(RP) :: TILE_LATE (tile_nlim)
246 real(RP) :: TILE_LONS (tile_nlim)
247 real(RP) :: TILE_LONE (tile_nlim)
249 character(len=H_LONG) :: fname
256 log_info(
"CNV2D_GrADS",*)
'Setup' 258 grads_missingval = undef
262 read(
io_fid_conf,nml=param_cnv2d_grads,iostat=ierr)
264 log_info(
"CNV2D_GrADS",*)
'Not found namelist. Default used.' 265 elseif( ierr > 0 )
then 266 log_error(
"CNV2D_GrADS",*)
'Not appropriate names in namelist PARAM_CNV2D_GrADS. Check!' 269 log_nml(param_cnv2d_grads)
271 if ( grads_nlat <= 0 )
then 272 log_error(
"CNV2D_GrADS",*)
'GrADS_NLAT (number of latitude tile) should be positive. Check!', grads_nlat
276 if ( grads_nlon <= 0 )
then 277 log_error(
"CNV2D_GrADS",*)
'GrADS_NLON (number of longitude tile) should be positive. Check!', grads_nlon
281 if ( grads_dlat <= 0.0_rp )
then 282 log_error(
"CNV2D_GrADS",*)
'GrADS_DLAT (width (deg.) of latitude tile) should be positive. Check!', grads_dlat
286 if ( grads_dlon <= 0.0_rp )
then 287 log_error(
"CNV2D_GrADS",*)
'GrADS_DLON (width (deg.) of longitude tile) should be positive. Check!', grads_dlon
291 if ( grads_in_catalogue ==
'' &
292 .AND. grads_in_filename ==
'' )
then 293 log_error(
"CNV2D_GrADS",*)
'Neither catalogue file nor single file do not specified. Check!' 297 if ( grads_in_datatype ==
'REAL8' )
then 298 log_info(
"CNV2D_GrADS",*)
'type of input data : REAL8' 299 elseif( grads_in_datatype ==
'REAL4' )
then 300 log_info(
"CNV2D_GrADS",*)
'type of input data : REAL4' 301 elseif( grads_in_datatype ==
'INT2' )
then 302 log_info(
"CNV2D_GrADS",*)
'type of input data : INT2' 304 log_error(
"CNV2D_GrADS",*)
'Not appropriate type for GrADS_IN_DATATYPE. Check!' 305 log_error_cont(*)
'REAL8, REAL4, INT2 are available. requested:', trim(grads_in_datatype)
309 if ( grads_latorder_n2s )
then 310 log_info(
"CNV2D_GrADS",*)
'data ordar of the latitude direction : North -> South' 312 log_info(
"CNV2D_GrADS",*)
'data ordar of the latitude direction : South -> North' 315 log_info(
"CNV2D_GrADS",*)
'Number of steps : ', grads_nstep
316 if ( grads_nstep > 1 )
then 318 log_info(
"CNV2D_GrADS",*)
'Time interval : ', var2d_dtsec
325 real_lonuy_mod(:,:) = mod( real_lonuy(:,:)+3.0_dp*pi, 2.0_dp*pi ) - pi
327 domain_lats = minval(real_latxv(:,:))
328 domain_late = maxval(real_latxv(:,:))
329 domain_lons = minval(real_lonuy_mod(:,:))
330 domain_lone = maxval(real_lonuy_mod(:,:))
331 domain_lonsloc = minloc(real_lonuy_mod(:,:))
332 domain_loneloc = maxloc(real_lonuy_mod(:,:))
335 if ( domain_lons < real_lonuy_mod( 0,domain_lonsloc(2)) &
336 .OR. domain_lone > real_lonuy_mod(
ia,domain_loneloc(2)) )
then 338 domain_lons = minval(real_lonuy_mod(:,:),mask=(real_lonuy_mod>0.0_rp))
339 domain_lone = maxval(real_lonuy_mod(:,:),mask=(real_lonuy_mod<0.0_rp))
342 tile_nlat = grads_nlat
343 tile_nlon = grads_nlon
344 log_info(
"CNV2D_GrADS",*)
'Size of data in each tile (j) = ', tile_nlat
345 log_info(
"CNV2D_GrADS",*)
'Size of data in each tile (i) = ', tile_nlon
347 tile_dlat = grads_dlat * d2r
348 tile_dlon = grads_dlon * d2r
349 log_info(
"CNV2D_GrADS",*)
'TILE_DLAT :', tile_dlat/d2r
350 log_info(
"CNV2D_GrADS",*)
'TILE_DLON :', tile_dlon/d2r
354 if ( grads_in_catalogue /=
'' )
then 357 fname = trim(grads_in_dir)//
'/'//trim(grads_in_catalogue)
360 log_info(
"CNV2D_GrADS",*)
'+ Input catalogue file:', trim(fname)
364 file = trim(fname), &
365 form =
'formatted', &
369 if ( ierr /= 0 )
then 370 log_error(
"CNV2D_GrADS",*)
'catalogue file not found!', trim(fname)
375 read(fid,*,iostat=ierr) index, tile_lats(t), tile_late(t), &
376 tile_lons(t), tile_lone(t), &
378 if ( ierr /= 0 )
exit 384 elseif( grads_in_filename /=
'' )
then 388 tile_fname(1) = grads_in_filename
389 tile_lats(1) = grads_lat_start
390 tile_late(1) = grads_lat_end
391 tile_lons(1) = grads_lon_start
392 tile_lone(1) = grads_lon_end
397 if ( tile_lons(t) >= 180.0_rp )
then 398 tile_lons(t) = tile_lons(t) - 360.0_rp
399 tile_lone(t) = tile_lone(t) - 360.0_rp
401 if ( tile_lons(t) < -180.0_rp ) tile_lons(t) = tile_lons(t) + 360.0_rp
402 if ( tile_lone(t) < -180.0_rp ) tile_lone(t) = tile_lone(t) + 360.0_rp
405 do nowstep = 1, grads_nstep
407 log_info(
"CNV2D_GrADS",*)
'step = ', nowstep
411 if ( cnv2d_interpolation_type ==
'bilinear' &
412 .OR. cnv2d_interpolation_type ==
'nearestneighbor' )
then 414 call cnv2d_grads_bilinear ( domain_lats, &
420 tile_fname(1:tile_nmax), &
421 tile_lats(1:tile_nmax), &
422 tile_late(1:tile_nmax), &
423 tile_lons(1:tile_nmax), &
424 tile_lone(1:tile_nmax), &
431 grads_latorder_n2s, &
436 elseif( cnv2d_interpolation_type ==
'areaweighted' )
then 438 call cnv2d_grads_areaweighted( domain_lats, &
444 tile_fname(1:tile_nmax), &
445 tile_lats(1:tile_nmax), &
446 tile_late(1:tile_nmax), &
447 tile_lons(1:tile_nmax), &
448 tile_lone(1:tile_nmax), &
455 grads_latorder_n2s, &
463 call cnv2d_write( var2d(:,:), &
469 end subroutine cnv2d_grads
473 subroutine cnv2d_grads_bilinear( &
506 real(RP),
intent(in) :: DOMAIN_LATS
507 real(RP),
intent(in) :: DOMAIN_LATE
508 real(RP),
intent(in) :: DOMAIN_LONS
509 real(RP),
intent(in) :: DOMAIN_LONE
510 integer,
intent(in) :: TILE_nmax
511 character(len=H_LONG),
intent(in) :: TILE_dir
512 character(len=H_LONG),
intent(in) :: TILE_fname(tile_nmax)
513 real(RP),
intent(in) :: TILE_LATS (tile_nmax)
514 real(RP),
intent(in) :: TILE_LATE (tile_nmax)
515 real(RP),
intent(in) :: TILE_LONS (tile_nmax)
516 real(RP),
intent(in) :: TILE_LONE (tile_nmax)
517 integer,
intent(in) :: TILE_NLAT
518 integer,
intent(in) :: TILE_NLON
519 real(RP),
intent(in) :: TILE_DLAT
520 real(RP),
intent(in) :: TILE_DLON
521 character(len=H_LONG),
intent(in) :: TILE_DATATYPE
522 logical,
intent(in) :: TILE_check_IDL
523 logical,
intent(in) :: TILE_LATORDER_N2S
524 real(RP),
intent(in) :: TILE_MISSINGVAL
525 integer,
intent(in) :: nowstep
526 real(RP),
intent(out) :: VAR2D(
ia,
ja)
528 real(RP) :: REAL_LON_mod(
ia,
ja)
530 real(RP) :: TILE_LAT (0:tile_nlat+1)
531 real(RP) :: TILE_LON (0:tile_nlon+1)
532 real(RP) :: TILE_VALUE (tile_nlon,tile_nlat)
533 real(DP) :: TILE_VALUE_DP(tile_nlon,tile_nlat)
534 real(SP) :: TILE_VALUE_SP(tile_nlon,tile_nlat)
535 integer(2) :: TILE_VALUE_I2(tile_nlon,tile_nlat)
544 character(len=H_LONG) :: fname
546 logical :: hit_lat, hit_lon
548 integer :: i, j, ii, jj, t
551 real_lon_mod(:,:) = mod( real_lon(:,:)+3.0_dp*pi, 2.0_dp*pi ) - pi
558 if ( ( tile_lats(t)*d2r >= domain_lats .AND. tile_lats(t)*d2r < domain_late ) &
559 .OR. ( tile_late(t)*d2r >= domain_lats .AND. tile_late(t)*d2r < domain_late ) )
then 563 if ( ( domain_lats >= tile_lats(t)*d2r .AND. domain_lats < tile_late(t)*d2r ) &
564 .OR. ( domain_late >= tile_lats(t)*d2r .AND. domain_late < tile_late(t)*d2r ) )
then 568 if ( tile_check_idl )
then 569 if ( ( tile_lons(t)*d2r >= domain_lons .AND. tile_lons(t)*d2r < pi ) &
570 .OR. ( tile_lons(t)*d2r >= -pi .AND. tile_lons(t)*d2r < domain_lone ) &
571 .OR. ( tile_lone(t)*d2r >= domain_lons .AND. tile_lone(t)*d2r < pi ) &
572 .OR. ( tile_lone(t)*d2r >= -pi .AND. tile_lone(t)*d2r < domain_lone ) )
then 576 if ( ( tile_lons(t)*d2r >= domain_lons .AND. tile_lons(t)*d2r < domain_lone ) &
577 .OR. ( tile_lone(t)*d2r >= domain_lons .AND. tile_lone(t)*d2r < domain_lone ) )
then 582 if ( ( domain_lons >= tile_lons(t)*d2r .AND. domain_lons < tile_lone(t)*d2r ) &
583 .OR. ( domain_lone >= tile_lons(t)*d2r .AND. domain_lone < tile_lone(t)*d2r ) )
then 587 if ( ( domain_lons+2.0_rp*pi >= tile_lons(t)*d2r .AND. domain_lons+2.0_rp*pi < tile_lone(t)*d2r ) &
588 .OR. ( domain_lone+2.0_rp*pi >= tile_lons(t)*d2r .AND. domain_lone+2.0_rp*pi < tile_lone(t)*d2r ) )
then 592 if ( hit_lat .AND. hit_lon )
then 593 fname = trim(tile_dir)//
'/'//trim(tile_fname(t))
596 log_info(
"CNV2D_GrADS_bilinear",*)
'+ Input data file :', trim(fname)
597 log_info_cont(*)
'Domain (LAT) :', domain_lats/d2r, domain_late/d2r
598 log_info_cont(*)
' (LON) :', domain_lons/d2r, domain_lone/d2r
599 if ( tile_check_idl )
then 600 log_info_cont(*)
'(Date line exists within the domain)' 602 log_info_cont(*)
'Tile (LAT) :', tile_lats(t), tile_late(t)
603 log_info_cont(*)
' (LON) :', tile_lons(t), tile_lone(t)
605 if ( tile_datatype ==
'REAL8' )
then 609 file = trim(fname), &
610 form =
'unformatted', &
613 recl = tile_nlon*tile_nlat*8, &
616 if ( ierr /= 0 )
then 617 log_error(
"CNV2D_GrADS_bilinear",*)
'data file not found!' 621 read(fid,rec=nowstep) tile_value_dp(:,:)
624 if ( tile_latorder_n2s )
then 627 tile_value(i,j) =
real( TILE_VALUE_DP(i,TILE_NLAT-j+1), kind=RP ) 633 tile_value(i,j) =
real( TILE_VALUE_DP(i,j), kind=
rp )
638 elseif( tile_datatype ==
'REAL4' )
then 642 file = trim(fname), &
643 form =
'unformatted', &
646 recl = tile_nlon*tile_nlat*4, &
649 if ( ierr /= 0 )
then 650 log_error(
"CNV2D_GrADS_bilinear",*)
'data file not found!' 654 read(fid,rec=nowstep) tile_value_sp(:,:)
657 if ( tile_latorder_n2s )
then 660 tile_value(i,j) =
real( TILE_VALUE_SP(i,TILE_NLAT-j+1), kind=RP ) 666 tile_value(i,j) =
real( TILE_VALUE_SP(i,j), kind=
rp )
671 elseif( tile_datatype ==
'INT2' )
then 675 file = trim(fname), &
676 form =
'unformatted', &
679 recl = tile_nlon*tile_nlat*2, &
682 if ( ierr /= 0 )
then 683 log_error(
"CNV2D_GrADS_bilinear",*)
'data file not found!' 687 read(fid,rec=nowstep) tile_value_i2(:,:)
690 if ( tile_latorder_n2s )
then 693 tile_value(i,j) =
real( TILE_VALUE_I2(i,TILE_NLAT-j+1), kind=RP ) 699 tile_value(i,j) =
real( TILE_VALUE_I2(i,j), kind=
rp )
706 call prof_valcheck(
'CNV2D',
'VAR',tile_value(:,:))
708 tile_lat(0) = tile_lats(t) * d2r - tile_dlat
709 do jj = 1, tile_nlat+1
710 tile_lat(jj) = tile_lat(jj-1) + tile_dlat
714 tile_lon(0) = tile_lons(t) * d2r - tile_dlon
715 do ii = 1, tile_nlon+1
716 tile_lon(ii) = tile_lon(ii-1) + tile_dlon
717 if( tile_lon(ii) > pi ) tile_lon(ii) = tile_lon(ii) - 2.0_rp*pi
722 do jj = 1, tile_nlat+1
723 do ii = 1, tile_nlon+1
724 if ( tile_lat(jj ) < domain_lats &
725 .OR. tile_lat(jj-1) > domain_late )
then 729 if ( tile_check_idl .OR. tile_lon(ii-1) >= tile_lon(ii) )
then 732 if ( tile_lon(ii ) < domain_lons &
733 .OR. tile_lon(ii-1) > domain_lone )
then 747 if ( real_lon_mod(i,j) >= tile_lon(ii-1) &
748 .AND. real_lon_mod(i,j) < tile_lon(ii ) &
749 .AND. real_lat(i,j) >= tile_lat(jj-1) &
750 .AND. real_lat(i,j) < tile_lat(jj ) )
then 754 ifrac_r = min( real_lon_mod(i,j)-tile_lon(ii-1), tile_dlon ) / tile_dlon
758 jfrac_t = min( real_lat(i,j)-tile_lat(jj-1), tile_dlat ) / tile_dlat
763 if ( tile_lon(ii-1) >= tile_lon(ii) &
764 .AND. real_lat(i,j) >= tile_lat(jj-1) &
765 .AND. real_lat(i,j) < tile_lat(jj ) )
then 767 if ( real_lon_mod(i,j) >= tile_lon(ii-1) &
768 .AND. real_lon_mod(i,j) < pi )
then 772 ifrac_r = min( real_lon_mod(i,j)-tile_lon(ii-1), tile_dlon ) / tile_dlon
776 jfrac_t = min( real_lat(i,j)-tile_lat(jj-1), tile_dlat ) / tile_dlat
778 elseif( real_lon_mod(i,j) >= -pi &
779 .AND. real_lon_mod(i,j) < tile_lon(ii ) )
then 783 ifrac_r = min( real_lon_mod(i,j)+2.0_rp*pi-tile_lon(ii-1), tile_dlon ) / tile_dlon
787 jfrac_t = min( real_lat(i,j)-tile_lat(jj-1), tile_dlat ) / tile_dlat
793 if( iloc_r == -1 .AND. jloc_t == -1 ) cycle
795 if( tile_lon(0) <= 0.0_rp .AND. iloc_l == 0 ) iloc_l = tile_nlon
796 if( tile_lon(tile_nlon+1) >= 0.0_rp .AND. iloc_r == tile_nlon+1 ) iloc_r = 1
798 if( tile_lat(0) <= -0.5_rp*pi .AND. jloc_b == 0 ) jloc_b = 1
799 if( tile_lat(tile_nlat+1) >= 0.5_rp*pi .AND. jloc_t == tile_nlat+1 ) jloc_t = tile_nlat
801 if ( cnv2d_interpolation_type ==
'nearestneighbor' )
then 802 if ( ifrac_r >= 0.5d0 )
then 808 if ( jfrac_t >= 0.5d0 )
then 815 var2d(i,j) = ( ifrac_r) * ( jfrac_t) * tile_value(iloc_r,jloc_t) &
816 + (1.0_rp-ifrac_r) * ( jfrac_t) * tile_value(iloc_l,jloc_t) &
817 + ( ifrac_r) * (1.0_rp-jfrac_t) * tile_value(iloc_r,jloc_b) &
818 + (1.0_rp-ifrac_r) * (1.0_rp-jfrac_t) * tile_value(iloc_l,jloc_b) + var2d(i,j)
830 end subroutine cnv2d_grads_bilinear
834 subroutine cnv2d_grads_areaweighted( &
868 real(RP),
intent(in) :: DOMAIN_LATS
869 real(RP),
intent(in) :: DOMAIN_LATE
870 real(RP),
intent(in) :: DOMAIN_LONS
871 real(RP),
intent(in) :: DOMAIN_LONE
872 integer,
intent(in) :: TILE_nmax
873 character(len=H_LONG),
intent(in) :: TILE_dir
874 character(len=H_LONG),
intent(in) :: TILE_fname(tile_nmax)
875 real(RP),
intent(in) :: TILE_LATS (tile_nmax)
876 real(RP),
intent(in) :: TILE_LATE (tile_nmax)
877 real(RP),
intent(in) :: TILE_LONS (tile_nmax)
878 real(RP),
intent(in) :: TILE_LONE (tile_nmax)
879 integer,
intent(in) :: TILE_NLAT
880 integer,
intent(in) :: TILE_NLON
881 real(RP),
intent(in) :: TILE_DLAT
882 real(RP),
intent(in) :: TILE_DLON
883 character(len=H_LONG),
intent(in) :: TILE_DATATYPE
884 logical,
intent(in) :: TILE_check_IDL
885 logical,
intent(in) :: TILE_LATORDER_N2S
886 real(RP),
intent(in) :: TILE_MISSINGVAL
887 integer,
intent(in) :: nowstep
888 real(RP),
intent(out) :: VAR2D(
ia,
ja)
890 real(RP) :: REAL_LONUY_mod(0:
ia,
ja)
892 real(RP) :: TILE_LATH (0:tile_nlat)
893 real(RP) :: TILE_LONH (0:tile_nlon)
894 real(RP) :: TILE_VALUE (tile_nlon,tile_nlat)
895 real(DP) :: TILE_VALUE_DP(tile_nlon,tile_nlat)
896 real(SP) :: TILE_VALUE_SP(tile_nlon,tile_nlat)
897 integer(2) :: TILE_VALUE_I2(tile_nlon,tile_nlat)
899 integer :: jloc, iloc
903 real(RP) :: val_sum (
ia,
ja)
904 real(RP) :: area_sum(
ia,
ja)
905 real(RP) :: val, mask
906 real(RP) :: area, area_fraction
908 character(len=H_LONG) :: fname
911 logical :: hit_lat, hit_lon
913 integer :: i, j, ii, jj, t
916 real_lonuy_mod(:,:) = mod( real_lonuy(:,:)+3.0_dp*pi, 2.0_dp*pi ) - pi
923 if ( ( tile_lats(t)*d2r >= domain_lats .AND. tile_lats(t)*d2r < domain_late ) &
924 .OR. ( tile_late(t)*d2r >= domain_lats .AND. tile_late(t)*d2r < domain_late ) )
then 928 if ( ( domain_lats >= tile_lats(t)*d2r .AND. domain_lats < tile_late(t)*d2r ) &
929 .OR. ( domain_late >= tile_lats(t)*d2r .AND. domain_late < tile_late(t)*d2r ) )
then 933 if ( tile_check_idl )
then 934 if ( ( tile_lons(t)*d2r >= domain_lons .AND. tile_lons(t)*d2r < pi ) &
935 .OR. ( tile_lons(t)*d2r >= -pi .AND. tile_lons(t)*d2r < domain_lone ) &
936 .OR. ( tile_lone(t)*d2r >= domain_lons .AND. tile_lone(t)*d2r < pi ) &
937 .OR. ( tile_lone(t)*d2r >= -pi .AND. tile_lone(t)*d2r < domain_lone ) )
then 941 if ( ( tile_lons(t)*d2r >= domain_lons .AND. tile_lons(t)*d2r < domain_lone ) &
942 .OR. ( tile_lone(t)*d2r >= domain_lons .AND. tile_lone(t)*d2r < domain_lone ) )
then 947 if ( ( domain_lons >= tile_lons(t)*d2r .AND. domain_lons < tile_lone(t)*d2r ) &
948 .OR. ( domain_lone >= tile_lons(t)*d2r .AND. domain_lone < tile_lone(t)*d2r ) )
then 952 if ( hit_lat .AND. hit_lon )
then 953 fname = trim(tile_dir)//
'/'//trim(tile_fname(t))
956 log_info(
"CNV2D_GrADS_areaweighted",*)
'+ Input data file :', trim(fname)
957 log_info_cont(*)
'Domain (LAT) :', domain_lats/d2r, domain_late/d2r
958 log_info_cont(*)
' (LON) :', domain_lons/d2r, domain_lone/d2r
959 if ( tile_check_idl )
then 960 log_info_cont(*)
'(Date line exists within the domain)' 962 log_info_cont(*)
'Tile (LAT) :', tile_lats(t), tile_late(t)
963 log_info_cont(*)
' (LON) :', tile_lons(t), tile_lone(t)
965 if ( tile_datatype ==
'REAL8' )
then 969 file = trim(fname), &
970 form =
'unformatted', &
973 recl = tile_nlon*tile_nlat*8, &
976 if ( ierr /= 0 )
then 977 log_error(
"CNV2D_GrADS_areaweighted",*)
'data file not found!' 981 read(fid,rec=nowstep) tile_value_dp(:,:)
984 if ( tile_latorder_n2s )
then 987 tile_value(i,j) =
real( TILE_VALUE_DP(i,TILE_NLAT-j+1), kind=RP ) 993 tile_value(i,j) =
real( TILE_VALUE_DP(i,j), kind=
rp )
998 elseif( tile_datatype ==
'REAL4' )
then 1002 file = trim(fname), &
1003 form =
'unformatted', &
1004 access =
'direct', &
1006 recl = tile_nlon*tile_nlat*4, &
1009 if ( ierr /= 0 )
then 1010 log_error(
"CNV2D_GrADS_areaweighted",*)
'data file not found!' 1014 read(fid,rec=nowstep) tile_value_sp(:,:)
1017 if ( tile_latorder_n2s )
then 1020 tile_value(i,j) =
real( TILE_VALUE_SP(i,TILE_NLAT-j+1), kind=RP ) 1026 tile_value(i,j) =
real( TILE_VALUE_SP(i,j), kind=
rp )
1031 elseif( tile_datatype ==
'INT2' )
then 1035 file = trim(fname), &
1036 form =
'unformatted', &
1037 access =
'direct', &
1039 recl = tile_nlon*tile_nlat*2, &
1042 if ( ierr /= 0 )
then 1043 log_error(
"CNV2D_GrADS_areaweighted",*)
'data file not found!' 1047 read(fid,rec=nowstep) tile_value_i2(:,:)
1050 if ( tile_latorder_n2s )
then 1053 tile_value(i,j) =
real( TILE_VALUE_I2(i,TILE_NLAT-j+1), kind=RP ) 1059 tile_value(i,j) =
real( TILE_VALUE_I2(i,j), kind=
rp )
1066 call prof_valcheck(
'CNV2D',
'VAR',tile_value(:,:))
1068 tile_lath(0) = tile_lats(t) * d2r
1069 do jj = 1, tile_nlat
1070 tile_lath(jj) = tile_lath(jj-1) + tile_dlat
1074 tile_lonh(0) = tile_lons(t) * d2r
1075 do ii = 1, tile_nlon
1076 tile_lonh(ii) = tile_lonh(ii-1) + tile_dlon
1077 if( tile_lonh(ii) > pi ) tile_lonh(ii) = tile_lonh(ii) - 2.0_rp*pi
1082 do jj = 1, tile_nlat
1083 do ii = 1, tile_nlon
1091 if ( tile_lath(jj ) < domain_lats &
1092 .OR. tile_lath(jj-1) > domain_late )
then 1096 if ( tile_check_idl )
then 1097 if ( tile_lonh(ii ) < domain_lons &
1098 .AND. tile_lonh(ii-1) > domain_lone )
then 1102 if ( tile_lonh(ii ) < domain_lons &
1103 .OR. tile_lonh(ii-1) > domain_lone )
then 1108 jloop:
do j =
js-1,
je+1
1109 iloop:
do i =
is-1,
ie+1
1110 if ( tile_lonh(ii-1) >= real_lonuy_mod(i-1,j ) &
1111 .AND. tile_lonh(ii-1) < real_lonuy_mod(i ,j ) &
1112 .AND. tile_lath(jj-1) >= real_latxv(i ,j-1) &
1113 .AND. tile_lath(jj-1) < real_latxv(i ,j ) )
then 1116 ifrac_l = min( real_lonuy_mod(i,j)-tile_lonh(ii-1), tile_dlon ) / tile_dlon
1119 jfrac_b = min( real_latxv(i,j)-tile_lath(jj-1), tile_dlat ) / tile_dlat
1124 if ( real_lonuy_mod(i-1,j) >= real_lonuy_mod(i ,j ) &
1125 .AND. tile_lath(jj-1) >= real_latxv(i ,j-1) &
1126 .AND. tile_lath(jj-1) < real_latxv(i ,j ) )
then 1128 if ( tile_lonh(ii-1) >= real_lonuy_mod(i-1,j) &
1129 .AND. tile_lonh(ii-1) < pi )
then 1132 ifrac_l = min( real_lonuy_mod(i,j)-tile_lonh(ii-1)+2.0_rp*pi, tile_dlon ) / tile_dlon
1135 jfrac_b = min( real_latxv(i,j)-tile_lath(jj-1), tile_dlat ) / tile_dlat
1138 elseif( tile_lonh(ii-1) >= -pi &
1139 .AND. tile_lonh(ii-1) < real_lonuy_mod(i ,j) )
then 1142 ifrac_l = min( real_lonuy_mod(i,j)-tile_lonh(ii-1), tile_dlon ) / tile_dlon
1145 jfrac_b = min( real_latxv(i,j)-tile_lath(jj-1), tile_dlat ) / tile_dlat
1154 if( iloc == 1 .AND. jloc == 1 ) cycle
1156 val = tile_value(ii,jj)
1159 if ( abs(val-tile_missingval) < eps ) mask = 1.0_rp
1161 area = radius * radius * tile_dlon * ( sin(tile_lath(jj))-sin(tile_lath(jj-1)) ) * ( 1.0_rp - mask )
1165 area_fraction = ( ifrac_l) * ( jfrac_b) * area
1166 area_sum(iloc ,jloc ) = area_sum(iloc ,jloc ) + area_fraction
1167 val_sum(iloc ,jloc ) = val_sum(iloc ,jloc ) + area_fraction * val
1169 area_fraction = (1.0_rp-ifrac_l) * ( jfrac_b) * area
1170 area_sum(iloc+1,jloc ) = area_sum(iloc+1,jloc ) + area_fraction
1171 val_sum(iloc+1,jloc ) = val_sum(iloc+1,jloc ) + area_fraction * val
1173 area_fraction = ( ifrac_l) * (1.0_rp-jfrac_b) * area
1174 area_sum(iloc ,jloc+1) = area_sum(iloc ,jloc+1) + area_fraction
1175 val_sum(iloc ,jloc+1) = val_sum(iloc ,jloc+1) + area_fraction * val
1177 area_fraction = (1.0_rp-ifrac_l) * (1.0_rp-jfrac_b) * area
1178 area_sum(iloc+1,jloc+1) = area_sum(iloc+1,jloc+1) + area_fraction
1179 val_sum(iloc+1,jloc+1) = val_sum(iloc+1,jloc+1) + area_fraction * val
1188 zerosw = 0.5_rp - sign( 0.5_rp, area_sum(i,j)-eps )
1189 var2d(i,j) = val_sum(i,j) * ( 1.0_rp-zerosw ) / ( area_sum(i,j)-zerosw )
1194 end subroutine cnv2d_grads_areaweighted
1204 real(RP),
intent(inout) :: VAR(
ia,
ja)
1206 logical,
intent(in),
optional :: FILL_BND
1208 logical :: FILL_BND_
1212 if (
present(fill_bnd) ) fill_bnd_ = fill_bnd
1214 call comm_vars8( var(:,:), 1 )
1215 call comm_wait ( var(:,:), 1, fill_bnd_ )
1222 subroutine cnv2d_write( &
1232 real(RP),
intent(in) :: VAR2D(
ia,
ja)
1233 real(DP),
intent(in) :: timeintv
1234 integer,
intent(in) :: istep
1236 real(RP) :: work(
ia,
ja,1)
1240 if ( cnv2d_out_basename /=
'' )
then 1242 log_info(
"CNV2D_write",*)
'Output converted 2D file ' 1244 work(:,:,1) = var2d(:,:)
1248 timeofs =
real(istep-1,kind=DP) * timeintv
1250 call file_cartesc_write( work(:,:,:), &
1251 cnv2d_out_basename, &
1253 cnv2d_out_varname, &
1254 cnv2d_out_vardesc, &
1255 cnv2d_out_varunit, &
1264 end subroutine cnv2d_write
subroutine, public calendar_unit2sec(second, value, unit)
Convert several units to second.
integer, public ia
of whole cells: x, local, with HALO
real(rp), dimension(:,:), allocatable, public atmos_grid_cartesc_real_lat
latitude [rad,-pi,pi]
real(rp), public const_radius
radius of the planet [m]
integer, public ja
of whole cells: y, local, with HALO
integer, public io_fid_conf
Config file ID.
real(rp), public const_d2r
degree to radian
real(rp), dimension(:,:), allocatable, public atmos_grid_cartesc_real_lon
longitude [rad,0-2pi]
real(rp), public const_undef
integer, public is
start point of inner domain: x, local
integer, public ie
end point of inner domain: x, local
logical, public cnv2d_donothing
real(rp), dimension(:,:), allocatable, public atmos_grid_cartesc_real_dlon
delta longitude
module atmosphere / grid / cartesC index
integer function, public io_get_available_fid()
search & get available file ID
integer, public je
end point of inner domain: y, local
real(rp), dimension(:,:), allocatable, public atmos_grid_cartesc_real_lonuy
longitude at staggered point (uy) [rad,0-2pi]
logical, public cnv2d_usegrads
subroutine, public cnv2d_setup
Setup.
real(rp), dimension(:,:), allocatable, public atmos_grid_cartesc_real_dlat
delta latitude
subroutine, public prc_abort
Abort Process.
integer, public js
start point of inner domain: y, local
subroutine cnv2d_fillhalo(VAR, FILL_BND)
HALO Communication.
real(rp), public const_eps
small number
module Atmosphere GRID CartesC Real(real space)
subroutine, public cnv2d
Driver.
real(rp), public const_pi
pi
real(rp), dimension(:,:), allocatable, public atmos_grid_cartesc_real_latxv
latitude at staggered point (xv) [rad,-pi,pi]
integer, dimension(6), public time_nowdate
current time [YYYY MM DD HH MM SS]
integer, parameter, public rp