SCALE-RM
scale_grid_real.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
13 !-------------------------------------------------------------------------------
15  !-----------------------------------------------------------------------------
16  !
17  !++ used modules
18  !
19  use scale_precision
20  use scale_stdio
21  use scale_prof
23  !-----------------------------------------------------------------------------
24  implicit none
25  private
26  !-----------------------------------------------------------------------------
27  !
28  !++ Public procedure
29  !
30  public :: real_setup
31  public :: real_update_z
32  public :: real_calc_areavol
33 
34  !-----------------------------------------------------------------------------
35  !
36  !++ Public parameters & variables
37  !
38  real(RP), public, allocatable :: real_lon(:,:)
39  real(RP), public, allocatable :: real_lat(:,:)
40  real(RP), public, allocatable :: real_cz (:,:,:)
41  real(RP), public, allocatable :: real_fz (:,:,:)
42 
43  real(RP), public :: real_basepoint_lon
44  real(RP), public :: real_basepoint_lat
45 
46  real(RP), public, allocatable :: real_lonx (:,:)
47  real(RP), public, allocatable :: real_lony (:,:)
48  real(RP), public, allocatable :: real_lonxy(:,:)
49  real(RP), public, allocatable :: real_latx (:,:)
50  real(RP), public, allocatable :: real_laty (:,:)
51  real(RP), public, allocatable :: real_latxy(:,:)
52  real(RP), public, allocatable :: real_dlon (:,:)
53  real(RP), public, allocatable :: real_dlat (:,:)
54 
55  real(RP), public, allocatable :: real_z1 (:,:)
56  real(RP), public :: real_aspect_max
57  real(RP), public :: real_aspect_min
58 
59  real(RP), public, allocatable :: real_phi (:,:,:)
60 
61  real(RP), public, allocatable :: real_area(:,:)
62  real(RP), public, allocatable :: real_vol (:,:,:)
63 
64  real(RP), public, allocatable :: real_domain_catalogue(:,:,:)
65 
66  real(RP), public :: real_totarea
67  real(RP), public :: real_totvol
68 
69  !-----------------------------------------------------------------------------
70  !
71  !++ Private procedure
72  !
73  private :: real_calc_latlon
74  private :: real_calc_z
75 
76  !-----------------------------------------------------------------------------
77  !
78  !++ Private parameters & variables
79  !
80  !-----------------------------------------------------------------------------
81 contains
82  !-----------------------------------------------------------------------------
84  subroutine real_setup
85  use scale_process, only: &
86  prc_nprocs, &
88  use scale_grid, only: &
91  use scale_mapproj, only: &
93  use scale_fileio, only: &
95  implicit none
96 
97  !---------------------------------------------------------------------------
98 
99  if( io_l ) write(io_fid_log,*)
100  if( io_l ) write(io_fid_log,*) '+++ Module[REAL]/Categ[GRID]'
101 
102  allocate( real_lon(ia,ja) )
103  allocate( real_lat(ia,ja) )
104  allocate( real_lonx(ia,ja) )
105  allocate( real_lony(ia,ja) )
106  allocate( real_lonxy(ia,ja) )
107  allocate( real_latx(ia,ja) )
108  allocate( real_laty(ia,ja) )
109  allocate( real_latxy(ia,ja) )
110  allocate( real_dlon(ia,ja) )
111  allocate( real_dlat(ia,ja) )
112 
113  allocate( real_cz( ka,ia,ja) )
114  allocate( real_fz(0:ka,ia,ja) )
115  allocate( real_z1( ia,ja) )
116  allocate( real_phi( ka,ia,ja) )
117 
118  allocate( real_area( ia,ja) )
119  allocate( real_vol(ka,ia,ja) )
120 
121  allocate( real_domain_catalogue(prc_nprocs,4,2) )
122 
123  ! setup map projection
125 
126  ! calc longitude & latitude
127  call real_calc_latlon
128 
129  ! calc real height
130  call real_calc_z
131 
132  ! calc control area & volume
133  ! call REAL_calc_areavol ! must be called after GTRANS_setup
134 
135  ! set latlon and z to fileio module
138  real_cz, real_fz )
139 
140  return
141  end subroutine real_setup
142 
143  !-----------------------------------------------------------------------------
145  subroutine real_update_z
146  use scale_process, only: &
148  use scale_fileio, only: &
150  implicit none
151  !---------------------------------------------------------------------------
152 
153  ! calc real height
154  call real_calc_z
155 
156  ! set latlon and z to fileio module
159  real_cz, real_fz )
160 
161  return
162  end subroutine real_update_z
163 
164  !-----------------------------------------------------------------------------
166  subroutine real_calc_latlon
167  use scale_const, only: &
168  d2r => const_d2r
169  use scale_grid, only: &
172  grid_cx, &
173  grid_cy, &
174  grid_fx, &
175  grid_fy
176  use scale_mapproj, only: &
180  use scale_process, only: &
181  prc_mpistop, &
182  prc_nprocs, &
184  use scale_comm, only: &
185  comm_gather, &
186  comm_bcast
187  implicit none
188 
189  real(RP), allocatable :: mine(:,:)
190  real(RP), allocatable :: whole(:,:)
191 
192  real(RP) :: CX, CY, FX, FY
193 
194  integer, parameter :: I_LON = 1
195  integer, parameter :: I_LAT = 2
196  integer, parameter :: I_NW = 1
197  integer, parameter :: I_NE = 2
198  integer, parameter :: I_SW = 3
199  integer, parameter :: I_SE = 4
200 
201  character(len=H_LONG) :: DOMAIN_CATALOGUE_FNAME = 'latlon_domain_catalogue.txt'
202  logical :: DOMAIN_CATALOGUE_OUTPUT = .false.
203 
204  namelist / param_domain_catalogue / &
205  domain_catalogue_fname, &
206  domain_catalogue_output
207 
208  integer :: i, j
209  integer :: fid, ierr
210  !---------------------------------------------------------------------------
211 
212  !--- read namelist
213  rewind(io_fid_conf)
214  read(io_fid_conf,nml=param_domain_catalogue,iostat=ierr)
215  if( ierr < 0 ) then !--- missing
216  if( io_l ) write(io_fid_log,*) '*** Not found namelist. Default used.'
217  elseif( ierr > 0 ) then !--- fatal error
218  write(*,*) 'xxx Not appropriate names in namelist PARAM_DOMAIN_CATALOGUE. Check!'
219  call prc_mpistop
220  endif
221  if( io_lnml ) write(io_fid_log,nml=param_domain_catalogue)
222 
225 
226  if( io_l ) write(io_fid_log,*)
227  if( io_l ) write(io_fid_log,*) '*** Base position in the global domain'
228  if( io_l ) write(io_fid_log,*) '->(',real_basepoint_lon/d2r,',',real_basepoint_lat/d2r,')'
229 
230  do j = 1, ja
231  do i = 1, ia
232  ! apply offset
233  cx = grid_cx(i) - grid_domain_center_x
234  cy = grid_cy(j) - grid_domain_center_y
235  fx = grid_fx(i) - grid_domain_center_x
236  fy = grid_fy(j) - grid_domain_center_y
237 
238  call mprj_xy2lonlat( grid_cx(i), grid_cy(j), real_lon(i,j), real_lat(i,j) )
239  call mprj_xy2lonlat( grid_fx(i), grid_cy(j), real_lonx(i,j), real_latx(i,j) )
240  call mprj_xy2lonlat( grid_cx(i), grid_fy(j), real_lony(i,j), real_laty(i,j) )
241  call mprj_xy2lonlat( grid_fx(i), grid_fy(j), real_lonxy(i,j), real_latxy(i,j) )
242  enddo
243  enddo
244 
245  real_dlon(:,:) = 0.0_rp
246  real_dlat(:,:) = 0.0_rp
247  do j = js, je
248  do i = is, ie
249  real_dlon(i,j) = real_lonx(i,j) - real_lonx(i-1,j)
250  real_dlat(i,j) = real_laty(i,j) - real_laty(i,j-1)
251  enddo
252  enddo
253 
254  if( io_l ) write(io_fid_log,*)
255  if( io_l ) write(io_fid_log,*) '*** Position on the earth (Local)'
256  if( io_l ) write(io_fid_log,'(1x,A,F10.5,A,F9.5,A,A,F10.5,A,F9.5,A)') &
257  'NW(',real_lon(is,je)/d2r,',',real_lat(is,je)/d2r,')-', &
258  'NE(',real_lon(ie,je)/d2r,',',real_lat(ie,je)/d2r,')'
259  if( io_l ) write(io_fid_log,'(1x,A)') &
260  ' | |'
261  if( io_l ) write(io_fid_log,'(1x,A,F10.5,A,F9.5,A,A,F10.5,A,F9.5,A)') &
262  'SW(',real_lon(is,js)/d2r,',',real_lat(is,js)/d2r,')-', &
263  'SE(',real_lon(ie,js)/d2r,',',real_lat(ie,js)/d2r,')'
264 
265 
266  allocate( mine(4, 2 ) )
267  allocate( whole(4, 2*prc_nprocs) )
268 
269  mine(i_nw,i_lon) = real_lonxy(is-1,je )/d2r
270  mine(i_ne,i_lon) = real_lonxy(ie ,je )/d2r
271  mine(i_sw,i_lon) = real_lonxy(is-1,js-1)/d2r
272  mine(i_se,i_lon) = real_lonxy(ie ,js-1)/d2r
273  mine(i_nw,i_lat) = real_latxy(is-1,je )/d2r
274  mine(i_ne,i_lat) = real_latxy(ie ,je )/d2r
275  mine(i_sw,i_lat) = real_latxy(is-1,js-1)/d2r
276  mine(i_se,i_lat) = real_latxy(ie ,js-1)/d2r
277 
278  call comm_gather( whole, mine, 4, 2 ) ! everytime do for online nesting
279 
280  if( prc_ismaster )then
281  if( domain_catalogue_output ) then
282  fid = io_get_available_fid()
283  open( fid, &
284  file = trim(domain_catalogue_fname), &
285  form = 'formatted', &
286  status = 'replace', &
287  iostat = ierr )
288 
289  if ( ierr /= 0 ) then
290  if( io_l ) write(*,*) 'xxx cannot create latlon-catalogue file!'
291  call prc_mpistop
292  endif
293 
294  do i = 1, prc_nprocs ! for offline nesting
295  write(fid,'(i8,8f32.24)',iostat=ierr) i, whole(i_nw,i_lon+2*(i-1)), whole(i_ne,i_lon+2*(i-1)), & ! LON: NW, NE
296  whole(i_sw,i_lon+2*(i-1)), whole(i_se,i_lon+2*(i-1)), & ! LON: SW, SE
297  whole(i_nw,i_lat+2*(i-1)), whole(i_ne,i_lat+2*(i-1)), & ! LAT: NW, NE
298  whole(i_sw,i_lat+2*(i-1)), whole(i_se,i_lat+2*(i-1)) ! LAT: SW, SE
299  if ( ierr /= 0 ) exit
300  enddo
301  close(fid)
302  endif
303 
304  do i = 1, prc_nprocs ! for online nesting
305  real_domain_catalogue(i,i_nw,i_lon) = whole(i_nw,i_lon+2*(i-1)) ! LON: NW
306  real_domain_catalogue(i,i_ne,i_lon) = whole(i_ne,i_lon+2*(i-1)) ! LON: NE
307  real_domain_catalogue(i,i_sw,i_lon) = whole(i_sw,i_lon+2*(i-1)) ! LON: SW
308  real_domain_catalogue(i,i_se,i_lon) = whole(i_se,i_lon+2*(i-1)) ! LON: SE
309  real_domain_catalogue(i,i_nw,i_lat) = whole(i_nw,i_lat+2*(i-1)) ! LAT: NW
310  real_domain_catalogue(i,i_ne,i_lat) = whole(i_ne,i_lat+2*(i-1)) ! LAT: NE
311  real_domain_catalogue(i,i_sw,i_lat) = whole(i_sw,i_lat+2*(i-1)) ! LAT: SW
312  real_domain_catalogue(i,i_se,i_lat) = whole(i_se,i_lat+2*(i-1)) ! LAT: SE
313  enddo
314  endif
315 
316  call comm_bcast( real_domain_catalogue, prc_nprocs, 4, 2 )
317 
318  return
319  end subroutine real_calc_latlon
320 
321  !-----------------------------------------------------------------------------
323  subroutine real_calc_z
324  use scale_const, only: &
325  grav => const_grav
326  use scale_grid, only: &
327  grid_cz, &
328  grid_fz, &
329  grid_cdx, &
330  grid_cdy
331  use scale_topography, only: &
332  zsfc => topo_zsfc
333  implicit none
334 
335  real(RP) :: Htop
336  real(RP) :: DFZ
337 
338  integer :: k, i, j
339  !---------------------------------------------------------------------------
340 
341  htop = grid_fz(ke) - grid_fz(ks-1)
342 
343  do j = 1, ja
344  do i = 1, ia
345  do k = 1, ka
346  real_cz(k,i,j) = ( htop - zsfc(i,j) ) / htop * grid_cz(k) + zsfc(i,j)
347  enddo
348  enddo
349  enddo
350 
351  do j = 1, ja
352  do i = 1, ia
353  do k = 0, ka
354  real_fz(k,i,j) = ( htop - zsfc(i,j) ) / htop * grid_fz(k) + zsfc(i,j)
355  enddo
356  enddo
357  enddo
358 
359  real_z1(:,:) = real_cz(ks,:,:) - zsfc(:,:)
360 
361  real_phi(:,:,:) = grav * real_cz(:,:,:)
362 
363  real_aspect_max = -1.e+30_rp
364  real_aspect_min = 1.e+30_rp
365  do j = js, je
366  do i = is, ie
367  do k = ks, ke
368  dfz = real_fz(k,i,j) - real_fz(k-1,i,j)
369  real_aspect_max = max( real_aspect_max, grid_cdx(i) / dfz, grid_cdy(j) / dfz )
370  real_aspect_min = min( real_aspect_min, grid_cdx(i) / dfz, grid_cdy(j) / dfz )
371  enddo
372  enddo
373  enddo
374 
375  if( io_l ) write(io_fid_log,*)
376  if( io_l ) write(io_fid_log,*) '*** Minimum & maximum aspect ratio'
377  if( io_l ) write(io_fid_log,*) '->(',real_aspect_min,',',real_aspect_max,')'
378 
379  return
380  end subroutine real_calc_z
381 
382  !-----------------------------------------------------------------------------
384  subroutine real_calc_areavol( &
385  MAPF )
386  use scale_const, only: &
387  radius => const_radius
388  use scale_grid, only: &
389  dz, &
390  dx, &
391  dy
392  implicit none
393  real(RP), intent(in) :: MAPF(ia,ja,2)
394 
395  integer :: k, i, j
396  !---------------------------------------------------------------------------
397 
398  real_totarea = 0.0_rp
399  real_area(:,:) = 0.0_rp
400  do j = js, je
401  do i = is, ie
402  real_area(i,j) = dx * dy / ( mapf(i,j,1) * mapf(i,j,2) )
404  enddo
405  enddo
406 
407  real_totvol = 0.0_rp
408  real_vol(:,:,:) = 0.0_rp
409  do j = js, je
410  do i = is, ie
411  do k = ks, ke
412  real_vol(k,i,j) = ( real_fz(k,i,j) - real_fz(k-1,i,j) ) * real_area(i,j)
413  real_totvol = real_totvol + real_vol(k,i,j)
414  enddo
415  enddo
416  enddo
417 
418  return
419  end subroutine real_calc_areavol
420 
421 end module scale_grid_real
integer, public is
start point of inner domain: x, local
real(rp), public grid_domain_center_x
center position of global domain [m]: x
integer, public je
end point of inner domain: y, local
logical, public prc_ismaster
master process in local communicator?
real(rp), public dy
length in the main region [m]: y
subroutine, public prc_mpistop
Abort MPI.
real(rp), public real_basepoint_lat
position of base point in real world [rad,-pi,pi]
real(rp), public mprj_basepoint_lat
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:59
real(rp), dimension(:), allocatable, public grid_cz
center coordinate [m]: z, local=global
subroutine, public mprj_xy2lonlat(x, y, lon, lat)
(x,y) -> (lon,lat)
real(rp), public const_radius
radius of the planet [m]
Definition: scale_const.F90:46
module STDIO
Definition: scale_stdio.F90:12
integer, public ke
end point of inner domain: z, local
real(rp), dimension(:,:,:), allocatable, public real_fz
geopotential height [m] (cell face )
real(rp), public real_aspect_max
maximum aspect ratio of the grid cell
real(rp), dimension(:,:,:), allocatable, public real_cz
geopotential height [m] (cell center)
real(rp), public const_d2r
degree to radian
Definition: scale_const.F90:35
real(rp), public mprj_basepoint_lon
module FILE I/O (netcdf)
real(rp), public dz
length in the main region [m]: z
real(rp), dimension(:), allocatable, public grid_fx
face coordinate [m]: x, local
module grid index
subroutine, public real_setup
Setup.
integer, public ia
of x whole cells (local, with HALO)
real(rp), dimension(:,:), allocatable, public real_latx
latitude at staggered point (uy) [rad,-pi,pi]
integer function, public io_get_available_fid()
search & get available file ID
real(rp), dimension(:,:), allocatable, public real_z1
Height of the lowermost grid from surface (cell center) [m].
module GRID (real space)
real(rp), dimension(:,:), allocatable, public real_dlon
delta longitude
integer, public ka
of z whole cells (local, with HALO)
real(rp), dimension(:,:), allocatable, public real_area
horizontal area [m2]
real(rp), dimension(:), allocatable, public grid_fz
face coordinate [m]: z, local=global
real(rp), dimension(:,:), allocatable, public real_lonxy
longitude at staggered point (uv) [rad,0-2pi]
real(rp), public real_aspect_min
minimum aspect ratio of the grid cell
module COMMUNICATION
Definition: scale_comm.F90:23
real(rp), public const_grav
standard acceleration of gravity [m/s2]
Definition: scale_const.F90:48
integer, public js
start point of inner domain: y, local
module PROCESS
real(rp), dimension(:,:), allocatable, public real_dlat
delta latitude
real(rp), dimension(:,:,:), allocatable, public real_vol
control volume [m3]
real(rp), public real_totvol
total volume (local) [m3]
module CONSTANT
Definition: scale_const.F90:14
integer, public ks
start point of inner domain: z, local
real(rp), dimension(:), allocatable, public grid_cx
center coordinate [m]: x, local
module GRID (cartesian)
real(rp), dimension(:,:,:), allocatable, public real_domain_catalogue
domain latlon catalogue [rad]
subroutine, public real_update_z
Re-setup with updated topography.
real(rp), public grid_domain_center_y
center position of global domain [m]: y
module profiler
Definition: scale_prof.F90:10
integer, public ie
end point of inner domain: x, local
subroutine, public real_calc_areavol(MAPF)
Calc control area/volume.
real(rp), dimension(:,:,:), allocatable, public real_phi
geopotential [m2/s2] (cell center)
logical, public io_lnml
output log or not? (for namelist, this process)
Definition: scale_stdio.F90:60
real(rp), public real_totarea
total area (local) [m2]
real(rp), dimension(:,:), allocatable, public real_lon
longitude [rad,0-2pi]
module PRECISION
real(rp), dimension(:,:), allocatable, public topo_zsfc
absolute ground height [m]
real(rp), dimension(:), allocatable, public grid_cdy
y-length of control volume [m]
module TOPOGRAPHY
subroutine, public fileio_set_coordinates(LON, LONX, LONY, LONXY, LAT, LATX, LATY, LATXY, CZ, FZ)
set latlon and z
integer, public io_fid_conf
Config file ID.
Definition: scale_stdio.F90:55
real(rp), dimension(:,:), allocatable, public real_lat
latitude [rad,-pi,pi]
real(rp), dimension(:,:), allocatable, public real_lony
longitude at staggered point (xv) [rad,0-2pi]
integer, public io_fid_log
Log file ID.
Definition: scale_stdio.F90:56
subroutine, public mprj_setup(DOMAIN_CENTER_X, DOMAIN_CENTER_Y)
Setup.
integer, public prc_nprocs
myrank in local communicator
real(rp), dimension(:,:), allocatable, public real_latxy
latitude at staggered point (uv) [rad,-pi,pi]
real(rp), dimension(:,:), allocatable, public real_lonx
longitude at staggered point (uy) [rad,0-2pi]
real(rp), dimension(:), allocatable, public grid_cdx
x-length of control volume [m]
real(rp), dimension(:), allocatable, public grid_cy
center coordinate [m]: y, local
real(rp), public real_basepoint_lon
position of base point in real world [rad,0-2pi]
module Map projection
real(rp), dimension(:,:), allocatable, public real_laty
latitude at staggered point (xv) [rad,-pi,pi]
integer, public ja
of y whole cells (local, with HALO)
real(rp), dimension(:), allocatable, public grid_fy
face coordinate [m]: y, local