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  character(len=H_LONG) :: domain_catalogue_fname = 'latlon_domain_catalogue.txt'
98  logical :: domain_catalogue_output = .false.
99 
100  namelist / param_domain_catalogue / &
101  domain_catalogue_fname, &
102  domain_catalogue_output
103 
104  integer :: ierr
105  !---------------------------------------------------------------------------
106 
107  if( io_l ) write(io_fid_log,*)
108  if( io_l ) write(io_fid_log,*) '++++++ Module[GRID_REAL] / Categ[ATMOS-RM GRID] / Origin[SCALElib]'
109 
110  !--- read namelist
111  rewind(io_fid_conf)
112  read(io_fid_conf,nml=param_domain_catalogue,iostat=ierr)
113  if( ierr < 0 ) then !--- missing
114  if( io_l ) write(io_fid_log,*) '*** Not found namelist. Default used.'
115  elseif( ierr > 0 ) then !--- fatal error
116  write(*,*) 'xxx Not appropriate names in namelist PARAM_DOMAIN_CATALOGUE. Check!'
117  call prc_mpistop
118  endif
119  if( io_nml ) write(io_fid_nml,nml=param_domain_catalogue)
120 
121  allocate( real_lon( ia, ja) )
122  allocate( real_lat( ia, ja) )
123  allocate( real_lonx(0:ia, ja) )
124  allocate( real_lony( ia,0:ja) )
125  allocate( real_lonxy(0:ia,0:ja) )
126  allocate( real_latx(0:ia, ja) )
127  allocate( real_laty( ia,0:ja) )
128  allocate( real_latxy(0:ia,0:ja) )
129  allocate( real_dlon( ia, ja) )
130  allocate( real_dlat( ia, ja) )
131 
132  allocate( real_cz( ka,ia,ja) )
133  allocate( real_fz(0:ka,ia,ja) )
134  allocate( real_z1( ia,ja) )
135  allocate( real_phi( ka,ia,ja) )
136 
137  allocate( real_area( ia,ja) )
138  allocate( real_vol(ka,ia,ja) )
139 
140  allocate( real_domain_catalogue(prc_nprocs,4,2) )
141 
142  ! setup map projection
144 
145  ! calc longitude & latitude
146  call real_calc_latlon( domain_catalogue_fname, domain_catalogue_output )
147 
148  ! calc real height
149  call real_calc_z
150 
151  ! calc control area & volume
152  ! call REAL_calc_areavol ! must be called after GTRANS_setup
153 
154  ! set latlon and z to fileio module
157  real_cz, real_fz )
158 
159  return
160  end subroutine real_setup
161 
162  !-----------------------------------------------------------------------------
164  subroutine real_update_z
165  use scale_process, only: &
167  use scale_fileio, only: &
169  implicit none
170  !---------------------------------------------------------------------------
171 
172  ! calc real height
173  call real_calc_z
174 
175  ! set latlon and z to fileio module
178  real_cz, real_fz )
179 
180  return
181  end subroutine real_update_z
182 
183  !-----------------------------------------------------------------------------
185  subroutine real_calc_latlon( &
186  catalogue_fname, &
187  catalogue_output )
188  use scale_process, only: &
189  prc_mpistop, &
190  prc_nprocs, &
192  use scale_const, only: &
193  pi => const_pi, &
194  d2r => const_d2r
195  use scale_grid, only: &
196  grid_cx, &
197  grid_cy, &
198  grid_fx, &
199  grid_fy
200  use scale_comm, only: &
201  comm_gather, &
202  comm_bcast
203  use scale_mapproj, only: &
207  implicit none
208 
209  character(len=*), intent(in) :: catalogue_fname
210  logical, intent(in) :: catalogue_output
211 
212  integer, parameter :: i_lon = 1
213  integer, parameter :: i_lat = 2
214  integer, parameter :: i_nw = 1
215  integer, parameter :: i_ne = 2
216  integer, parameter :: i_sw = 3
217  integer, parameter :: i_se = 4
218 
219  real(RP) :: mine (4,2)
220  real(RP) :: whole(4,2*prc_nprocs)
221 
222  integer :: i, j
223  integer :: fid, ierr
224  !---------------------------------------------------------------------------
225 
228 
229  if( io_l ) write(io_fid_log,*)
230  if( io_l ) write(io_fid_log,*) '*** Base position in the global domain (lat,lon)'
231  if( io_l ) write(io_fid_log,*) '*** ->(',real_basepoint_lon/d2r,',',real_basepoint_lat/d2r,')'
232 
233  do j = 1, ja
234  do i = 1, ia
235  call mprj_xy2lonlat( grid_cx(i), grid_cy(j), real_lon(i,j), real_lat(i,j) )
236  enddo
237  enddo
238 
239  do j = 1, ja
240  do i = 0, ia
241  call mprj_xy2lonlat( grid_fx(i), grid_cy(j), real_lonx(i,j), real_latx(i,j) )
242  enddo
243  enddo
244 
245  do j = 0, ja
246  do i = 1, ia
247  call mprj_xy2lonlat( grid_cx(i), grid_fy(j), real_lony(i,j), real_laty(i,j) )
248  enddo
249  enddo
250 
251  do j = 0, ja
252  do i = 0, ia
253  call mprj_xy2lonlat( grid_fx(i), grid_fy(j), real_lonxy(i,j), real_latxy(i,j) )
254  enddo
255  enddo
256 
257  real_dlon(:,:) = 0.0_rp
258  real_dlat(:,:) = 0.0_rp
259  do j = js, je
260  do i = is, ie
261  real_dlon(i,j) = real_lonx(i,j) - real_lonx(i-1,j)
262  real_dlat(i,j) = real_laty(i,j) - real_laty(i,j-1)
263  if( real_dlon(i,j) < 0.0_rp ) real_dlon(i,j) = real_dlon(i,j) + 2.0_rp*pi
264 
265  if ( real_dlon(i,j) == 0.0_rp &
266  .OR. real_dlat(i,j) == 0.0_rp ) then
267  write(*,*) 'xxx Invalid grid distance in lat-lon! i,j=', i,j
268  write(*,*) 'xxx Lon(i-1),Lon(i),dlon=', real_lonx(i-1,j)/d2r,real_lonx(i,j)/d2r,real_dlon(i,j)/d2r
269  write(*,*) 'xxx Lat(j-1),Lat(j),dlat=', real_laty(i,j-1)/d2r,real_laty(i,j)/d2r,real_dlat(i,j)/d2r
270  call prc_mpistop
271  endif
272  enddo
273  enddo
274 
275  if( io_l ) write(io_fid_log,*)
276  if( io_l ) write(io_fid_log,*) '*** Position on the earth (Local)'
277  if( io_l ) write(io_fid_log,'(1x,A,F10.5,A,F9.5,A,A,F10.5,A,F9.5,A)') &
278  '*** NW(',real_lon(is,je)/d2r,',',real_lat(is,je)/d2r,')', &
279  ' - NE(',real_lon(ie,je)/d2r,',',real_lat(ie,je)/d2r,')'
280 
281  if( io_l ) write(io_fid_log,'(1x,A)') &
282  '*** | |'
283  if( io_l ) write(io_fid_log,'(1x,A,F10.5,A,F9.5,A,A,F10.5,A,F9.5,A)') &
284  '*** SW(',real_lon(is,js)/d2r,',',real_lat(is,js)/d2r,')', &
285  ' - SE(',real_lon(ie,js)/d2r,',',real_lat(ie,js)/d2r,')'
286 
287  mine(i_nw,i_lon) = real_lonxy(is-1,je )/d2r
288  mine(i_ne,i_lon) = real_lonxy(ie ,je )/d2r
289  mine(i_sw,i_lon) = real_lonxy(is-1,js-1)/d2r
290  mine(i_se,i_lon) = real_lonxy(ie ,js-1)/d2r
291  mine(i_nw,i_lat) = real_latxy(is-1,je )/d2r
292  mine(i_ne,i_lat) = real_latxy(ie ,je )/d2r
293  mine(i_sw,i_lat) = real_latxy(is-1,js-1)/d2r
294  mine(i_se,i_lat) = real_latxy(ie ,js-1)/d2r
295 
296  call comm_gather( whole(:,:), mine(:,:), 4, 2 ) ! everytime do for online nesting
297 
298  if ( prc_ismaster ) then
299  if ( catalogue_output ) then
300 
301  fid = io_get_available_fid()
302  open( fid, &
303  file = trim(catalogue_fname), &
304  form = 'formatted', &
305  status = 'replace', &
306  iostat = ierr )
307 
308  if ( ierr /= 0 ) then
309  write(*,*) 'xxx [REAL_calc_latlon] cannot create latlon-catalogue file!'
310  call prc_mpistop
311  endif
312 
313  do i = 1, prc_nprocs ! for offline nesting
314  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
315  whole(i_sw,i_lon+2*(i-1)), whole(i_se,i_lon+2*(i-1)), & ! LON: SW, SE
316  whole(i_nw,i_lat+2*(i-1)), whole(i_ne,i_lat+2*(i-1)), & ! LAT: NW, NE
317  whole(i_sw,i_lat+2*(i-1)), whole(i_se,i_lat+2*(i-1)) ! LAT: SW, SE
318  if ( ierr /= 0 ) exit
319  enddo
320 
321  close(fid)
322 
323  endif
324 
325  do i = 1, prc_nprocs ! for online nesting
326  real_domain_catalogue(i,i_nw,i_lon) = whole(i_nw,i_lon+2*(i-1)) ! LON: NW
327  real_domain_catalogue(i,i_ne,i_lon) = whole(i_ne,i_lon+2*(i-1)) ! LON: NE
328  real_domain_catalogue(i,i_sw,i_lon) = whole(i_sw,i_lon+2*(i-1)) ! LON: SW
329  real_domain_catalogue(i,i_se,i_lon) = whole(i_se,i_lon+2*(i-1)) ! LON: SE
330  real_domain_catalogue(i,i_nw,i_lat) = whole(i_nw,i_lat+2*(i-1)) ! LAT: NW
331  real_domain_catalogue(i,i_ne,i_lat) = whole(i_ne,i_lat+2*(i-1)) ! LAT: NE
332  real_domain_catalogue(i,i_sw,i_lat) = whole(i_sw,i_lat+2*(i-1)) ! LAT: SW
333  real_domain_catalogue(i,i_se,i_lat) = whole(i_se,i_lat+2*(i-1)) ! LAT: SE
334  enddo
335  endif
336 
337  call comm_bcast( real_domain_catalogue(:,:,:), prc_nprocs, 4, 2 )
338 
339  return
340  end subroutine real_calc_latlon
341 
342  !-----------------------------------------------------------------------------
344  subroutine real_calc_z
345  use scale_const, only: &
346  grav => const_grav
347  use scale_grid, only: &
348  grid_cz, &
349  grid_fz, &
350  grid_cdx, &
351  grid_cdy
352  use scale_topography, only: &
353  zsfc => topo_zsfc
354  implicit none
355 
356  real(RP) :: htop
357  real(RP) :: dfz
358 
359  integer :: k, i, j
360  !---------------------------------------------------------------------------
361 
362  htop = grid_fz(ke) - grid_fz(ks-1)
363 
364  do j = 1, ja
365  do i = 1, ia
366  do k = 1, ka
367  real_cz(k,i,j) = ( htop - zsfc(i,j) ) / htop * grid_cz(k) + zsfc(i,j)
368  enddo
369  enddo
370  enddo
371 
372  do j = 1, ja
373  do i = 1, ia
374  do k = 0, ka
375  real_fz(k,i,j) = ( htop - zsfc(i,j) ) / htop * grid_fz(k) + zsfc(i,j)
376  enddo
377  enddo
378  enddo
379 
380  real_z1(:,:) = real_cz(ks,:,:) - zsfc(:,:)
381 
382  real_phi(:,:,:) = grav * real_cz(:,:,:)
383 
384  real_aspect_max = -1.e+30_rp
385  real_aspect_min = 1.e+30_rp
386  do j = js, je
387  do i = is, ie
388  do k = ks, ke
389  dfz = real_fz(k,i,j) - real_fz(k-1,i,j)
390  real_aspect_max = max( real_aspect_max, grid_cdx(i) / dfz, grid_cdy(j) / dfz )
391  real_aspect_min = min( real_aspect_min, grid_cdx(i) / dfz, grid_cdy(j) / dfz )
392  enddo
393  enddo
394  enddo
395 
396  if( io_l ) write(io_fid_log,*)
397  if( io_l ) write(io_fid_log,*) '*** Minimum & maximum aspect ratio'
398  if( io_l ) write(io_fid_log,*) '*** ->(',real_aspect_min,',',real_aspect_max,')'
399 
400  return
401  end subroutine real_calc_z
402 
403  !-----------------------------------------------------------------------------
405  subroutine real_calc_areavol( &
406  MAPF )
407  use scale_const, only: &
408  radius => const_radius
409  use scale_grid, only: &
410  dz, &
411  dx, &
412  dy
413  implicit none
414  real(RP), intent(in) :: mapf(ia,ja,2)
415 
416  integer :: k, i, j
417  !---------------------------------------------------------------------------
418 
419  real_totarea = 0.0_rp
420  real_area(:,:) = 0.0_rp
421  do j = js, je
422  do i = is, ie
423  real_area(i,j) = dx * dy / ( mapf(i,j,1) * mapf(i,j,2) )
425  enddo
426  enddo
427 
428  real_totvol = 0.0_rp
429  real_vol(:,:,:) = 0.0_rp
430  do j = js, je
431  do i = is, ie
432  do k = ks, ke
433  real_vol(k,i,j) = ( real_fz(k,i,j) - real_fz(k-1,i,j) ) * real_area(i,j)
434  real_totvol = real_totvol + real_vol(k,i,j)
435  enddo
436  enddo
437  enddo
438 
439  return
440  end subroutine real_calc_areavol
441 
442 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:61
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
logical, public io_nml
output log or not? (for namelist, this process)
Definition: scale_stdio.F90:62
subroutine, public real_setup
Setup.
integer, public ia
of whole cells: x, 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 whole cells: z, 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)
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
real(rp), public const_pi
pi
Definition: scale_const.F90:34
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]
integer, public io_fid_nml
Log file ID (only for output namelist)
Definition: scale_stdio.F90:57
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 whole cells: y, local, with HALO
real(rp), dimension(:), allocatable, public grid_fy
face coordinate [m]: y, local