SCALE-RM
mod_copytopo.f90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
9 !-------------------------------------------------------------------------------
11  !-----------------------------------------------------------------------------
12  !
13  !++ used modules
14  !
15  use gtool_file_h
16  use gtool_file, only: &
17  fileread
18  use scale_precision
19  use scale_stdio
20  use scale_prof
22  use scale_tracer
23  !-----------------------------------------------------------------------------
24  implicit none
25  private
26  !-----------------------------------------------------------------------------
27  !
28  !++ Public procedure
29  !
30  public :: copytopo
31 
32  !-----------------------------------------------------------------------------
33  !
34  !++ Public parameters & variables
35  !
36  integer, public :: cnvtopo_type = -1
37 
38  integer, public, parameter :: i_ignore = 0
39  integer, public, parameter :: i_gtopo30 = 1
40  integer, public, parameter :: i_dem50m = 2
41  integer, public, parameter :: i_gmted2010 = 3
42 
43  !-----------------------------------------------------------------------------
44  !
45  !++ Private procedure
46  !
47  private :: copytopo_transgrid
48  private :: copytopo_setalpha
49  private :: copytopo_input_data
50  private :: copytopo_mix_data
51 
52  !-----------------------------------------------------------------------------
53  !
54  !++ Private parameters & variables
55  !
56  integer, private, parameter :: handle = 1
57  integer, private :: itp_nh = 4
58 
59  character(len=H_LONG), private :: copytopo_in_basename = ''
60 
61  real(RP), private :: copytopo_transition_dx = -1.0_rp
62  real(RP), private :: copytopo_transition_dy = -1.0_rp
63  real(RP), private :: copytopo_transfact = -1.0_rp
64  real(RP), private :: copytopo_fracx = 1.0_rp
65  real(RP), private :: copytopo_fracy = 1.0_rp
66  real(RP), private :: copytopo_taux = 1.0_rp
67  real(RP), private :: copytopo_tauy = 1.0_rp
68 
69  logical, private :: copytopo_entire_region = .false.
70  logical, private :: copytopo_linear_h = .true.
71  real(RP), private :: copytopo_exp_h = 2.0_rp
72 
73  real(RP), private, allocatable :: ctrx(:)
74  real(RP), private, allocatable :: ctry(:)
75  real(RP), private, allocatable :: copytopo_alpha(:,:)
76  real(RP), private, allocatable :: topo_pd(:,:)
77 
78  !-----------------------------------------------------------------------------
79 contains
80  !-----------------------------------------------------------------------------
82  subroutine copytopo( &
83  topo_cd ) ! [inout]
84  use scale_process, only: &
86  use scale_grid, only: &
87  dx, &
88  dy, &
89  buffer_dx, &
90  buffer_dy, &
91  bufffact
92  use scale_grid_nest, only: &
94  implicit none
95 
96  real(RP), intent(inout) :: topo_cd(:,:)
97 
98  namelist / param_copytopo / &
99  copytopo_in_basename, &
100  copytopo_transition_dx, &
101  copytopo_transition_dy, &
102  copytopo_transfact, &
103  copytopo_fracx, &
104  copytopo_fracy, &
105  copytopo_taux, &
106  copytopo_tauy, &
107  copytopo_entire_region, &
108  copytopo_linear_h, &
109  copytopo_exp_h
110 
111  integer :: ierr
112  !---------------------------------------------------------------------------
113 
114  if( io_l ) write(io_fid_log,*)
115  if( io_l ) write(io_fid_log,*) '+++ Module[COPYTOPO]/Categ[COPYTOPO]'
116 
117  !--- read namelist
118  rewind(io_fid_conf)
119  read(io_fid_conf,nml=param_copytopo,iostat=ierr)
120  if( ierr < 0 ) then !--- missing
121  if( io_l ) write(io_fid_log,*) '*** Not found namelist. Default used.'
122  elseif( ierr > 0 ) then !--- fatal error
123  write(*,*) 'xxx Not appropriate names in namelist PARAM_COPYTOPO. Check!'
124  call prc_mpistop
125  endif
126  if( io_nml ) write(io_fid_nml,nml=param_copytopo)
127 
128  if ( copytopo_transition_dx < 0.0_rp ) then
129  copytopo_transition_dx = buffer_dx
130  end if
131  if ( copytopo_transition_dy < 0.0_rp ) then
132  copytopo_transition_dy = buffer_dy
133  end if
134  if ( copytopo_transfact < 0.0_rp ) then
135  copytopo_transfact = bufffact
136  end if
137 
138  allocate( ctrx(ia) )
139  allocate( ctry(ja) )
140  allocate( copytopo_alpha(ia,ja) )
141  allocate( topo_pd(ia,ja) )
142  copytopo_alpha(:,:) = 0.0_rp
143 
144  itp_nh = int( nest_interp_level )
145 
146  ! copy topography from parent domain to transition region
147  call copytopo_transgrid
148 
149  call copytopo_setalpha
150 
151  call copytopo_input_data( topo_pd ) ! (out)
152 
153  call copytopo_mix_data( topo_cd, & ! (inout)
154  topo_pd ) ! (in)
155 
156  return
157  end subroutine copytopo
158 
159  !-----------------------------------------------------------------------------
161  !-----------------------------------------------------------------------------
162 
163  !-----------------------------------------------------------------------------
165  subroutine copytopo_transgrid
166  use scale_process, only: &
167  prc_mpistop, &
168  prc_myrank
169  use scale_rm_process, only: &
170  prc_2drank, &
171  prc_num_x, &
172  prc_num_y
173  use scale_const, only: &
174  radius => const_radius, &
175  eps => const_eps
176  use scale_grid, only: &
177  dx, &
178  dy, &
179  cxg => grid_cxg, &
180  fxg => grid_fxg, &
181  cyg => grid_cyg, &
182  fyg => grid_fyg, &
183  cbfxg => grid_cbfxg, &
184  cbfyg => grid_cbfyg, &
185  bufffact
186  implicit none
187 
188  real(RP), allocatable :: ctrxg(:)
189  real(RP), allocatable :: ctryg(:)
190 
191  real(RP), allocatable :: buffx(:), buffy(:)
192  real(RP) :: bufftotx, bufftoty
193  real(RP), allocatable :: transx(:), transy(:)
194  real(RP) :: transtotx, transtoty
195 
196  integer :: imain, ibuff, itrans
197  integer :: jmain, jbuff, jtrans
198  integer :: copy_is, copy_ie, copy_js, copy_je
199 
200  integer :: i, j, ii, jj
201  !---------------------------------------------------------------------------
202 
203  allocate( buffx(0:iag) )
204  allocate( buffy(0:jag) )
205  allocate( transx(0:iag) )
206  allocate( transy(0:jag) )
207  allocate( ctrxg( iag) )
208  allocate( ctryg( jag) )
209 
210  ! X-direction
211  ! calculate buffer grid size
212  buffx(:) = dx
213  transx(0) = dx
214  bufftotx = 0.0_rp
215  transtotx = 0.0_rp
216 
217  do i = ihalo+1, iag
218  if( abs(cbfxg(i) - 0.0_rp) < eps ) exit
219  buffx(i) = buffx(i-1) * bufffact
220  bufftotx = bufftotx + buffx(i)
221  enddo
222  ibuff = i - (ihalo+1)
223 
224  do i = 1, iag
225  if( transtotx >= copytopo_transition_dx ) exit
226  transx(i) = transx(i-1) * copytopo_transfact
227  transtotx = transtotx + transx(i)
228  enddo
229  itrans = i - 1
230  imain = iag - 2*ibuff - 2*itrans - 2*ihalo
231 
232  if ( imain < 1 ) then
233  write(*,*) 'xxx Not appropriate transition width for global domain(X).', copytopo_transition_dx
234  write(*,*) ' # of buffer region (one side)', ibuff
235  write(*,*) ' # of transion region (one side)', itrans
236  call prc_mpistop
237  endif
238 
239  ! calc transition factor (global domaim)
240  ctrxg(:) = 0.0_rp
241  do i = 1, ihalo+ibuff
242  ctrxg(i) = 1.0_rp
243  enddo
244 
245  if ( itrans > 0 ) then
246  copy_is = ihalo+ibuff+1
247  copy_ie = ihalo+ibuff+itrans
248  do i = copy_is, copy_ie
249  ctrxg(i) = (transtotx+bufftotx+fxg(ihalo )-cxg(i)) / transtotx
250  enddo
251  copy_is = ihalo+ibuff+itrans+imain+1
252  copy_ie = ihalo+ibuff+itrans+imain+itrans+ibuff
253  do i = copy_is, copy_ie
254  ctrxg(i) = (transtotx+bufftotx-fxg(iag-ihalo)+cxg(i)) / transtotx
255  enddo
256  endif
257 
258  copy_is = ihalo+ibuff+itrans+imain+itrans+ibuff+1
259  copy_ie = ihalo+ibuff+itrans+imain+itrans+ibuff+ihalo
260  do i = copy_is, copy_ie
261  ctrxg(i) = 1.0_rp
262  enddo
263  ctrxg(:) = max( min( ctrxg(:), 1.0_rp ), 0.0_rp )
264 
265  ! Y-direction
266  ! calculate buffer grid size
267  buffy(:) = dy
268  transy(0) = dy
269  bufftoty = 0.0_rp
270  transtoty = 0.0_rp
271 
272  do j = jhalo+1, jag
273  if( abs(cbfyg(j) - 0.0_rp) < eps ) exit
274  buffy(j) = buffy(j-1) * bufffact
275  bufftoty = bufftoty + buffy(j)
276  enddo
277  jbuff = j - (jhalo+1)
278 
279  do j = 1, jag
280  if( transtoty >= copytopo_transition_dy ) exit
281  transy(j) = transy(j-1) * copytopo_transfact
282  transtoty = transtoty + transy(j)
283  enddo
284  jtrans = j - 1
285  jmain = jag - 2*jbuff - 2*jtrans - 2*jhalo
286 
287  if ( jmain < 1 ) then
288  write(*,*) 'xxx Not appropriate transition width for global domain(Y).', copytopo_transition_dy
289  write(*,*) ' # of buffer region (one side)', jbuff
290  write(*,*) ' # of transion region (one side)', jtrans
291  call prc_mpistop
292  endif
293 
294  ! calc transition factor (global domaim)
295  ctryg(:) = 0.0_rp
296  do j = 1, jhalo+jbuff
297  ctryg(j) = 1.0_rp
298  enddo
299 
300  if ( jtrans > 0 ) then
301  copy_js = jhalo+jbuff+1
302  copy_je = jhalo+jbuff+jtrans
303  do j = copy_js, copy_je
304  ctryg(j) = (transtoty+bufftoty+fyg(jhalo )-cyg(j)) / transtoty
305  enddo
306  copy_js = jhalo+jbuff+jtrans+jmain+1
307  copy_je = jhalo+jbuff+jtrans+jmain+jtrans+jbuff
308  do j = copy_js, copy_je
309  ctryg(j) = (transtoty+bufftoty-fyg(jag-jhalo)+cyg(j)) / transtoty
310  enddo
311  endif
312 
313  copy_js = jhalo+jbuff+jtrans+jmain+jtrans+jbuff+1
314  copy_je = jhalo+jbuff+jtrans+jmain+jtrans+jbuff+jhalo
315  do j = copy_js, copy_je
316  ctryg(j) = 1.0_rp
317  enddo
318  ctryg(:) = max( min( ctryg(:), 1.0_rp ), 0.0_rp )
319 
320  ! horizontal coordinate (local domaim)
321  do i = 1, ia
322  ii = i + prc_2drank(prc_myrank,1) * imax
323  ctrx(i) = ctrxg(ii)
324  enddo
325  do j = 1, ja
326  jj = j + prc_2drank(prc_myrank,2) * jmax
327  ctry(j) = ctryg(jj)
328  enddo
329 
330  deallocate( transx )
331  deallocate( transy )
332 
333  return
334  end subroutine copytopo_transgrid
335 
336 
337  !-----------------------------------------------------------------------------
339  subroutine copytopo_setalpha
340  use scale_const, only: &
341  eps => const_eps
342  use scale_comm, only: &
343  comm_vars8, &
344  comm_wait
345 
346  real(RP) :: coef_x, alpha_x1
347  real(RP) :: coef_y, alpha_y1
348  real(RP) :: ee1
349 
350  integer :: i, j
351  !---------------------------------------------------------------------------
352 
353  ! check invalid fraction
354  copytopo_fracx = max( min( copytopo_fracx, 1.0_rp ), eps )
355  copytopo_fracy = max( min( copytopo_fracy, 1.0_rp ), eps )
356 
357  if ( copytopo_taux <= 0.0_rp ) then ! invalid tau
358  coef_x = 0.0_rp
359  else
360  coef_x = 1.0_rp / copytopo_taux
361  endif
362 
363  if ( copytopo_tauy <= 0.0_rp ) then ! invalid tau
364  coef_y = 0.0_rp
365  else
366  coef_y = 1.0_rp / copytopo_tauy
367  endif
368 
369  do j = 1, ja
370  do i = 1, ia
371  ee1 = ctrx(i)
372  if ( ee1 <= 1.0_rp - copytopo_fracx ) then
373  ee1 = 0.0_rp
374  else
375  ee1 = ( ee1 - 1.0_rp + copytopo_fracx ) / copytopo_fracx
376  endif
377 
378  if ( copytopo_linear_h ) then
379  alpha_x1 = coef_x * ee1
380  else
381  alpha_x1 = coef_x * ee1 * exp( -(1.0_rp-ee1) * copytopo_exp_h )
382  end if
383 
384  ee1 = ctry(j)
385  if ( ee1 <= 1.0_rp - copytopo_fracy ) then
386  ee1 = 0.0_rp
387  else
388  ee1 = ( ee1 - 1.0_rp + copytopo_fracy ) / copytopo_fracy
389  endif
390 
391  if ( copytopo_linear_h ) then
392  alpha_y1 = coef_y * ee1
393  else
394  alpha_y1 = coef_y * ee1 * exp( -(1.0_rp-ee1) * copytopo_exp_h )
395  end if
396 
397  copytopo_alpha(i,j) = max( alpha_x1, alpha_y1 )
398  enddo
399  enddo
400 
401  call comm_vars8( copytopo_alpha(:,:), 1 )
402  call comm_wait ( copytopo_alpha(:,:), 1 )
403 
404  return
405  end subroutine copytopo_setalpha
406 
407 
408  !-----------------------------------------------------------------------------
410  subroutine copytopo_input_data( &
411  topo_pd ) ! (out)
412  use scale_const, only: &
413  d2r => const_d2r
414  use scale_comm, only: &
415  comm_vars8, &
416  comm_wait
417  use scale_grid_nest, only: &
418  parent_imax, &
419  parent_jmax, &
420  nest_tile_num_x, &
421  nest_tile_num_y, &
422  nest_tile_id, &
424  use scale_interpolation_nest, only: &
428  use scale_grid_real, only: &
429  lat => real_lat, &
430  lon => real_lon
431  implicit none
432 
433  real(RP), intent(out) :: topo_pd(:,:)
434 
435  real(RP) :: dummy (1,1,1)
436  real(RP), allocatable :: read2d(:,:)
437  real(RP), allocatable :: lon_org (:,:)
438  real(RP), allocatable :: lat_org (:,:)
439  real(RP), allocatable :: topo_org(:,:)
440  real(RP), allocatable :: hfact(:,:,:)
441  integer, allocatable :: igrd (:,:,:)
442  integer, allocatable :: jgrd (:,:,:)
443 
444  integer :: iall, jall ! number of grids for whole domain
445  integer :: pti, ptj ! number of grids for a tile
446  integer :: tilei, tilej
447  integer :: rank
448  integer :: i
449  integer :: cxs, cxe, cys, cye ! for child domain
450  integer :: pxs, pxe, pys, pye ! for parent domain
451  !---------------------------------------------------------------------------
452 
453  pti = parent_imax(handle)
454  ptj = parent_jmax(handle)
455  iall = pti * nest_tile_num_x
456  jall = ptj * nest_tile_num_y
457 
458  allocate( hfact( ia, ja, itp_nh ) )
459  allocate( igrd( ia, ja, itp_nh ) )
460  allocate( jgrd( ia, ja, itp_nh ) )
461  allocate( lon_org( iall, jall ) )
462  allocate( lat_org( iall, jall ) )
463  allocate( topo_org( iall, jall ) )
464 
465  do i = 1, size( nest_tile_id(:) )
466  ! read data from split files
467  rank = nest_tile_id(i)
468 
469  call nest_domain_shape ( tilei, tilej, & ! [out]
470  cxs, cxe, & ! [out]
471  cys, cye, & ! [out]
472  pxs, pxe, & ! [out]
473  pys, pye, & ! [out]
474  i ) ! [in ]
475  allocate( read2d( tilei,tilej ) )
476 
477  call fileread( read2d(:,:), copytopo_in_basename, "lon", 1, rank )
478  lon_org(cxs:cxe,cys:cye) = read2d(pxs:pxe,pys:pye) * d2r
479  call fileread( read2d(:,:), copytopo_in_basename, "lat", 1, rank )
480  lat_org(cxs:cxe,cys:cye) = read2d(pxs:pxe,pys:pye) * d2r
481  call fileread( read2d(:,:), copytopo_in_basename, "TOPO", 1, rank )
482  topo_org(cxs:cxe,cys:cye) = read2d(pxs:pxe,pys:pye)
483 
484  deallocate( read2d )
485  end do
486 
487  call intrpnest_domain_compatibility( lon_org(:,:), lat_org(:,:), dummy(:,:,:), &
488  lon(:,:), lat(:,:), dummy(:,:,:), &
489  skip_z=.true. )
490  !call check_domain_compatibility( lon_org(:,:), lat_org(:,:), dummy(:,:,:), &
491  ! LON(:,:), LAT(:,:), dummy(:,:,:), &
492  ! skip_z=.true. )
493 
494  call intrpnest_interp_fact_latlon( hfact(:,:,:), & ! (out)
495  igrd(:,:,:), & ! (out)
496  jgrd(:,:,:), & ! (out)
497  lat(:,:), & ! (in)
498  lon(:,:), & ! (in)
499  ia, ja, & ! (in)
500  lat_org(:,:), & ! (in)
501  lon_org(:,:), & ! (in)
502  iall, jall ) ! (in)
503 
504  call intrpnest_interp_2d( topo_pd(:,:), &
505  topo_org(:,:), &
506  hfact(:,:,:), &
507  igrd(:,:,:), &
508  jgrd(:,:,:), &
509  ia, ja )
510 
511  call comm_vars8( topo_pd(:,:), 1 )
512  call comm_wait ( topo_pd(:,:), 1 )
513 
514  return
515  end subroutine copytopo_input_data
516 
517  !-----------------------------------------------------------------------------
519  subroutine copytopo_mix_data( &
520  topo_cd, & ! (inout)
521  topo_pd ) ! (in)
522  implicit none
523  real(RP), intent(inout) :: topo_cd(:,:) ! topography of child domain (mine)
524  real(RP), intent(in) :: topo_pd(:,:) ! topography of parent domain
525 
526  real(RP) :: frac
527  integer :: i, j
528  !---------------------------------------------------------------------------
529 
530  if ( copytopo_entire_region ) then
531  topo_cd(:,:) = topo_pd(:,:)
532  else
533  do j = 1, ja
534  do i = 1, ia
535  frac = copytopo_alpha(i,j)
536  topo_cd(i,j) = topo_cd(i,j) * ( 1.0_rp - frac ) &
537  + topo_pd(i,j) * frac
538  end do
539  end do
540  endif
541 
542  return
543  end subroutine copytopo_mix_data
544 
545 end module mod_copytopo
integer, public imax
of computational cells: x, local
integer, public prc_num_x
x length of 2D processor topology
real(rp), public buffer_dx
thickness of buffer region [m]: x
module GTOOL_FILE
Definition: gtool_file.f90:17
subroutine, public intrpnest_domain_compatibility(lon_org, lat_org, lev_org, lon_loc, lat_loc, lev_loc, skip_x, skip_y, skip_z)
real(rp), public dy
length in the main region [m]: y
real(rp), dimension(:), allocatable, public grid_cyg
center coordinate [m]: y, global
subroutine, public prc_mpistop
Abort MPI.
real(rp), dimension(:), allocatable, public grid_cbfyg
center buffer factor (0-1): y, global
integer, parameter, public i_dem50m
integer, dimension(2), public parent_jmax
parent max number in y-direction
module GRID (nesting system)
real(rp), dimension(:), allocatable, public grid_cxg
center coordinate [m]: x, global
real(rp), public dx
length in the main region [m]: x
logical, public io_l
output log or not? (this process)
Definition: scale_stdio.F90:61
real(rp), dimension(:), allocatable, public grid_fxg
face coordinate [m]: x, global
real(rp), public const_radius
radius of the planet [m]
Definition: scale_const.F90:46
module STDIO
Definition: scale_stdio.F90:12
real(rp), public const_d2r
degree to radian
Definition: scale_const.F90:35
procedure(intrpnest_intfc_interp_2d), pointer, public intrpnest_interp_2d
integer, dimension(:), allocatable, public nest_tile_id
parent tile real id
integer, public nest_interp_level
horizontal interpolation level
subroutine, public intrpnest_interp_fact_latlon(hfact, igrd, jgrd, mylat, mylon, myIA, myJA, inlat, inlon, inIA, inJA)
module Copy topography
integer, parameter, public i_gtopo30
integer, public prc_num_y
y length of 2D processor topology
module grid index
logical, public io_nml
output log or not? (for namelist, this process)
Definition: scale_stdio.F90:62
module TRACER
subroutine, public nest_domain_shape(tilei, tilej, cxs, cxe, cys, cye, pxs, pxe, pys, pye, iloc)
Return shape of ParentDomain at the specified rank (for offline)
integer, public ia
of whole cells: x, local, with HALO
integer, public jag
of computational grids
module GRID (real space)
integer, parameter, public i_gmted2010
integer, parameter, public i_ignore
integer, public jhalo
of halo cells: y
module COMMUNICATION
Definition: scale_comm.F90:23
integer, public iag
of computational grids
module PROCESS
integer, public nest_tile_num_y
parent tile number in y-direction
module CONSTANT
Definition: scale_const.F90:14
integer, public prc_myrank
process num in local communicator
module GRID (cartesian)
module INTERPOLATION (nesting system)
module RM PROCESS
subroutine, public copytopo(topo_cd)
Setup and Main.
real(rp), public buffer_dy
thickness of buffer region [m]: y
module profiler
Definition: scale_prof.F90:10
integer, dimension(2), public parent_imax
parent max number in x-direction
real(rp), public const_eps
small number
Definition: scale_const.F90:36
real(rp), dimension(:,:), allocatable, public real_lon
longitude [rad,0-2pi]
integer, public nest_tile_num_x
parent tile number in x-direction
integer, public cnvtopo_type
module PRECISION
integer, dimension(:,:), allocatable, public prc_2drank
node index in 2D topology
module FILE I/O HEADER
integer, public io_fid_conf
Config file ID.
Definition: scale_stdio.F90:55
real(rp), dimension(:,:), allocatable, public real_lat
latitude [rad,-pi,pi]
integer, public io_fid_log
Log file ID.
Definition: scale_stdio.F90:56
real(rp), public bufffact
default strech factor for dx/dy/dz of buffer region
integer, public jmax
of computational cells: y, local
integer, public io_fid_nml
Log file ID (only for output namelist)
Definition: scale_stdio.F90:57
real(rp), dimension(:), allocatable, public grid_fyg
face coordinate [m]: y, global
real(rp), dimension(:), allocatable, public grid_cbfxg
center buffer factor (0-1): x, global
integer, public ihalo
of halo cells: x
integer, public ja
of whole cells: y, local, with HALO