38 private :: copytopo_transgrid
39 private :: copytopo_setalpha
40 private :: copytopo_input_data
41 private :: copytopo_mix_data
47 integer,
private,
parameter :: handle = 1
49 character(len=H_SHORT),
private :: COPYTOPO_IN_FILETYPE =
''
50 character(len=H_LONG),
private :: COPYTOPO_IN_BASENAME =
''
51 character(len=H_LONG),
private :: COPYTOPO_IN_POSTFIX =
''
52 character(len=H_SHORT),
private :: COPYTOPO_IN_VARNAME =
'topo'
53 character(len=H_SHORT),
private :: COPYTOPO_IN_LONNAME =
'lon'
54 character(len=H_SHORT),
private :: COPYTOPO_IN_LATNAME =
'lat'
55 real(RP),
private :: COPYTOPO_TRANSITION_DX = -1.0_rp
56 real(RP),
private :: COPYTOPO_TRANSITION_DY = -1.0_rp
57 real(RP),
private :: COPYTOPO_FRACX = 1.0_rp
58 real(RP),
private :: COPYTOPO_FRACY = 1.0_rp
59 real(RP),
private :: COPYTOPO_taux = 1.0_rp
60 real(RP),
private :: COPYTOPO_tauy = 1.0_rp
61 logical,
private :: COPYTOPO_ENTIRE_REGION = .false.
62 logical,
private :: COPYTOPO_LINEAR_H = .true.
63 real(RP),
private :: COPYTOPO_EXP_H = 2.0_rp
64 character(len=H_SHORT),
private :: COPYTOPO_INTRP_TYPE =
"LINEAR"
65 integer,
private :: COPYTOPO_hypdiff_ORDER = 4
66 integer,
private :: COPYTOPO_hypdiff_NITER = 20
78 real(rp),
intent(inout) :: topo_child(:,:)
82 real(rp) :: alpha (
ia,
ja)
83 real(rp) :: topo_parent(
ia,
ja)
85 namelist / param_copytopo / &
86 copytopo_in_filetype, &
87 copytopo_in_basename, &
88 copytopo_in_postfix, &
89 copytopo_in_varname, &
90 copytopo_in_lonname, &
91 copytopo_in_latname, &
92 copytopo_transition_dx, &
93 copytopo_transition_dy, &
98 copytopo_entire_region, &
101 copytopo_hypdiff_order, &
102 copytopo_hypdiff_niter
108 log_info(
"COPYTOPO",*)
'Setup'
114 log_info(
"COPYTOPO",*)
'Not found namelist. Default used.'
115 elseif( ierr > 0 )
then
116 log_error(
"COPYTOPO",*)
'Not appropriate names in namelist PARAM_COPYTOPO. Check!'
119 log_nml(param_copytopo)
123 call copytopo_transgrid( ctrx(:), ctry(:) )
125 call copytopo_setalpha ( ctrx(:), ctry(:), &
128 call copytopo_input_data( topo_parent(:,:) )
130 call copytopo_mix_data( topo_parent(:,:), &
139 subroutine copytopo_transgrid( &
158 real(rp),
intent(out) :: ctrx(
ia)
159 real(rp),
intent(out) :: ctry(
ja)
161 real(rp) :: ctrxg (
iag)
162 real(rp) :: ctryg (
jag)
164 real(rp) :: bufftotx, transtotx
165 real(rp) :: bufftoty, transtoty
166 integer :: imain, ibuff, itrans
167 integer :: jmain, jbuff, jtrans
168 integer :: copy_is, copy_ie
169 integer :: copy_js, copy_je
171 integer :: i, j, ii, jj
178 if( abs(cbfxg(i)) < eps )
exit
180 ibuff = i - 1 -
ihalo
181 if ( ibuff == 0 )
then
187 if ( copytopo_transition_dx < 0.0_rp )
then
188 copytopo_transition_dx = bufftotx
191 if( cxg(i) - bufftotx - fxg(
ihalo) >= copytopo_transition_dx )
exit
193 itrans = i - 1 -
ihalo - ibuff
194 if ( itrans == 0 )
then
197 transtotx = fxg(itrans+ibuff+
ihalo) - fxg(
ihalo) - bufftotx
200 imain =
iag - 2*ibuff - 2*itrans - 2*
ihalo
202 if ( imain < 1 )
then
203 log_error(
"COPYTOPO_transgrid",*)
'Not appropriate transition width for global domain(X).', copytopo_transition_dx
204 log_error_cont(*)
'# of buffer region (one side) = ', ibuff
205 log_error_cont(*)
'# of transion region (one side) = ', itrans
213 copy_ie =
ihalo+ibuff
215 do i = copy_is, copy_ie
219 if ( itrans > 0 )
then
220 copy_is =
ihalo+ibuff+1
221 copy_ie =
ihalo+ibuff+itrans
223 do i = copy_is, copy_ie
224 ctrxg(i) = (transtotx+bufftotx+fxg(
ihalo )-cxg(i)) / transtotx
226 copy_is =
iag -
ihalo - ibuff - itrans + 1
229 do i = copy_is, copy_ie
230 ctrxg(i) = (transtotx+bufftotx-fxg(
iag-
ihalo)+cxg(i)) / transtotx
237 do i = copy_is, copy_ie
241 ctrxg(:) = max( min( ctrxg(:), 1.0_rp ), 0.0_rp )
246 if( abs(cbfyg(j)) < eps )
exit
248 jbuff = j - 1 -
jhalo
249 if ( jbuff == 0 )
then
255 if ( copytopo_transition_dy < 0.0_rp )
then
256 copytopo_transition_dy = bufftoty
259 if( cyg(j) - bufftoty - fyg(
jhalo) >= copytopo_transition_dy )
exit
261 jtrans = j - 1 -
jhalo - jbuff
262 if ( jtrans == 0 )
then
265 transtoty = fyg(jtrans+jbuff+
jhalo) - fyg(
jhalo) - bufftoty
268 jmain =
jag - 2*jbuff - 2*jtrans - 2*
jhalo
270 if ( jmain < 1 )
then
271 log_error(
"COPYTOPO_transgrid",*)
'Not appropriate transition width for global domain(Y).', copytopo_transition_dy
272 log_error_cont(*)
'# of buffer region (one side)', jbuff
273 log_error_cont(*)
'# of transion region (one side)', jtrans
281 copy_je =
jhalo+jbuff
283 do j = copy_js, copy_je
287 if ( jtrans > 0 )
then
288 copy_js =
jhalo+jbuff+1
289 copy_je =
jhalo+jbuff+jtrans
291 do j = copy_js, copy_je
292 ctryg(j) = (transtoty+bufftoty+fyg(
jhalo )-cyg(j)) / transtoty
294 copy_js =
jag -
jhalo - jbuff - jtrans + 1
297 do j = copy_js, copy_je
298 ctryg(j) = (transtoty+bufftoty-fyg(
jag-
jhalo)+cyg(j)) / transtoty
305 do j = copy_js, copy_je
309 ctryg(:) = max( min( ctryg(:), 1.0_rp ), 0.0_rp )
328 log_info(
"COPYTOPO_transgrid",*)
'COPYTOPO grid Information'
329 log_info_cont(*)
'size of buffer region (x and y; one side) = ', bufftotx, bufftoty
330 log_info_cont(*)
'# of buffer region (x and y; one side) = ', ibuff, jbuff
331 log_info_cont(*)
'size of transion region (x and y; one side) = ', transtotx, transtoty
332 log_info_cont(*)
'# of transion region (x and y; one side) = ', itrans, jtrans
336 end subroutine copytopo_transgrid
341 subroutine copytopo_setalpha( &
352 real(rp),
intent(in) :: ctrx (
ia)
353 real(rp),
intent(in) :: ctry (
ja)
354 real(rp),
intent(out) :: alpha(
ia,
ja)
356 real(rp) :: coef_x, alpha_x1
357 real(rp) :: coef_y, alpha_y1
364 copytopo_fracx = max( min( copytopo_fracx, 1.0_rp ), eps )
365 copytopo_fracy = max( min( copytopo_fracy, 1.0_rp ), eps )
367 if ( copytopo_taux <= 0.0_rp )
then
370 coef_x = 1.0_rp / copytopo_taux
373 if ( copytopo_tauy <= 0.0_rp )
then
376 coef_y = 1.0_rp / copytopo_tauy
385 if ( ee1 <= 1.0_rp - copytopo_fracx )
then
388 ee1 = ( ee1 - 1.0_rp + copytopo_fracx ) / copytopo_fracx
391 if ( copytopo_linear_h )
then
392 alpha_x1 = coef_x * ee1
394 alpha_x1 = coef_x * ee1 * exp( -(1.0_rp-ee1) * copytopo_exp_h )
399 if ( ee1 <= 1.0_rp - copytopo_fracy )
then
402 ee1 = ( ee1 - 1.0_rp + copytopo_fracy ) / copytopo_fracy
405 if ( copytopo_linear_h )
then
406 alpha_y1 = coef_y * ee1
408 alpha_y1 = coef_y * ee1 * exp( -(1.0_rp-ee1) * copytopo_exp_h )
411 alpha(i,j) = max( alpha_x1, alpha_y1 )
415 call comm_vars8( alpha(:,:), 1 )
416 call comm_wait ( alpha(:,:), 1 )
419 end subroutine copytopo_setalpha
424 subroutine copytopo_input_data( &
447 mapprojection_lonlat2xy
456 real(rp),
intent(out) :: topo_parent(:,:)
458 integer :: ia_org, ja_org
460 real(rp),
allocatable :: lon_org (:,:), lat_org(:,:)
461 real(rp),
allocatable :: x_org (:,:), y_org (:,:)
462 real(rp),
allocatable :: topo_org(:,:)
467 real(rp) :: dummy(1,1)
468 integer :: idx_i(
ia,
ja,nest_interp_level)
469 integer :: idx_j(
ia,
ja,nest_interp_level)
470 real(rp) :: hfact(
ia,
ja,nest_interp_level)
471 integer :: interp_level
472 logical :: zonal, pole
474 real(rp) :: topo_sign(
ia,
ja)
475 real(rp) :: ocean_flag
480 select case ( copytopo_in_filetype )
482 call copytopo_get_size_scale( ia_org, ja_org )
491 log_error(
"COPYTOPO_input_data",*)
'COPYTOPO_IN_FILETYPE must be "SCALE" or "GrADS"'
496 call comm_bcast( ia_org )
497 call comm_bcast( ja_org )
500 allocate( lon_org(ia_org,ja_org) )
501 allocate( lat_org(ia_org,ja_org) )
502 allocate( topo_org(ia_org,ja_org) )
504 select case ( copytopo_in_filetype )
507 lon_org(:,:), lat_org(:,:), topo_org(:,:) )
511 lon_org(:,:), lat_org(:,:), topo_org(:,:) )
515 lon_org(:,:), lat_org(:,:), topo_org(:,:) )
519 call comm_bcast( lon_org(:,:), ia_org, ja_org )
520 call comm_bcast( lat_org(:,:), ia_org, ja_org )
521 call comm_bcast( topo_org(:,:), ia_org, ja_org )
525 lon(:,:), lat(:,:), dummy(:,:), dummy(:,:), &
528 select case ( copytopo_intrp_type )
531 allocate( x_org(ia_org,ja_org) )
532 allocate( y_org(ia_org,ja_org) )
533 call mapprojection_lonlat2xy( ia_org, 1, ia_org, ja_org, 1, ja_org, &
534 lon_org(:,:), lat_org(:,:), &
535 x_org(:,:), y_org(:,:) )
537 zonal = ( maxval(lon_org) - minval(lon_org) ) > 2.0_rp * pi * 0.9_rp
538 pole = ( maxval(lat_org) > pi * 0.5_rp * 0.9_rp ) .or. ( minval(lat_org) < - pi * 0.5_rp * 0.9_rp )
539 call interp_factor2d( ia_org, ja_org,
ia,
ja, &
540 x_org(:,:), y_org(:,:), &
542 idx_i(:,:,:), idx_j(:,:,:), &
544 zonal = zonal, pole = pole )
545 deallocate( x_org, y_org )
548 case (
"DIST-WEIGHT" )
550 call interp_factor2d( nest_interp_level, &
551 ia_org, ja_org,
ia,
ja, &
552 lon_org(:,:), lat_org(:,:), &
553 lon(:,:), lat(:,:), &
554 idx_i(:,:,:), idx_j(:,:,:), &
556 interp_level = nest_interp_level
559 log_error(
"COPYTOPO_input_data",*)
"Unsupported type of COPYTOPO_INTRP_TYPE : ", trim(copytopo_intrp_type)
560 log_error_cont(*)
'It must be "LINEAR" or "DIST-WEIGHT"'
573 deallocate( topo_org, lon_org, lat_org )
575 if ( copytopo_hypdiff_niter > 1 )
then
581 * ( 0.5_rp + sign( 0.5_rp, eps - abs(topo_parent(i,j)) ) )
582 topo_sign(i,j) = sign( 1.0_rp, topo_parent(i,j) ) * ( 1.0_rp - ocean_flag )
587 topo_parent(:,:), copytopo_hypdiff_order, copytopo_hypdiff_niter, &
588 limiter_sign = topo_sign(:,:) )
592 call comm_vars8( topo_parent(:,:), 1 )
593 call comm_wait ( topo_parent(:,:), 1 )
597 end subroutine copytopo_input_data
601 subroutine copytopo_mix_data( &
607 real(rp),
intent(in) :: topo_parent(:,:)
608 real(rp),
intent(in) :: alpha (:,:)
609 real(rp),
intent(inout) :: topo_child (:,:)
614 if ( copytopo_entire_region )
then
618 topo_child(i,j) = topo_parent(i,j)
625 topo_child(i,j) = ( 1.0_rp-alpha(i,j) ) * topo_child(i,j) &
626 + ( alpha(i,j) ) * topo_parent(i,j)
632 end subroutine copytopo_mix_data
635 subroutine copytopo_get_size_scale( &
643 integer,
intent(out) :: ia_org
644 integer,
intent(out) :: ja_org
650 end subroutine copytopo_get_size_scale
667 integer,
intent(in) :: IA_org, JA_org
668 real(RP),
intent(out) :: LON_org (IA_org,JA_org)
669 real(RP),
intent(out) :: LAT_org (IA_org,JA_org)
670 real(RP),
intent(out) :: TOPO_org(IA_org,JA_org)
672 real(RP),
allocatable :: read2D(:,:)
674 integer :: tilei, tilej
675 integer :: cxs, cxe, cys, cye
676 integer :: pxs, pxe, pys, pye
682 do n = 1,
size( nest_tile_id(:) )
684 rank = nest_tile_id(n)
686 call nest_domain_shape( tilei, tilej, &
693 allocate( read2d(tilei,tilej) )
697 aggregate=.false., rankid=rank )
699 call file_read( fid,
"lon", read2d(:,:) )
700 lon_org(cxs:cxe,cys:cye) = read2d(pxs:pxe,pys:pye) * d2r
701 call file_read( fid,
"lat", read2d(:,:) )
702 lat_org(cxs:cxe,cys:cye) = read2d(pxs:pxe,pys:pye) * d2r
703 call file_read( fid, copytopo_in_varname, read2d(:,:) )
704 topo_org(cxs:cxe,cys:cye) = read2d(pxs:pxe,pys:pye)
721 integer,
intent(out) :: IA_org, JA_org
729 call file_grads_get_shape( file_id, copytopo_in_varname, &
752 integer,
intent(in) :: IA_org, JA_org
753 real(RP),
intent(out) :: LON_org (IA_org,JA_org)
754 real(RP),
intent(out) :: LAT_org (IA_org,JA_org)
755 real(RP),
intent(out) :: TOPO_org(IA_org,JA_org)
757 integer :: file_id, var_id
758 real(RP) :: lon1D(IA_org), lat1D(JA_org)
769 call file_grads_read( file_id, var_id, &
774 lon_org(i,j) = lon1d(i) * d2r
778 call file_grads_read( file_id, var_id, &
780 postfix = copytopo_in_postfix )
784 lon_org(i,j) = lon_org(i,j) * d2r
793 call file_grads_read( file_id, var_id, &
798 lat_org(i,j) = lat1d(j) * d2r
802 call file_grads_read( file_id, var_id, &
804 postfix = copytopo_in_postfix )
808 lat_org(i,j) = lat_org(i,j) * d2r
816 call file_grads_read( file_id, var_id, &
818 postfix = copytopo_in_postfix )
836 integer,
intent(out) :: IA_org, JA_org
842 postfix = copytopo_in_postfix, &
862 integer,
intent(in) :: IA_org, JA_org
863 real(RP),
intent(out) :: LON_org (IA_org,JA_org)
864 real(RP),
intent(out) :: LAT_org (IA_org,JA_org)
865 real(RP),
intent(out) :: TOPO_org(IA_org,JA_org)
872 postfix = copytopo_in_postfix, &
875 call file_read( fid,
"XLAT", lat_org(:,:) )
877 call file_read( fid,
"XLONG", lon_org(:,:) )
882 lat_org(i,j) = lat_org(i,j) * d2r
883 lon_org(i,j) = lon_org(i,j) * d2r
887 call file_read( fid,
"HGT", topo_org(:,:) )