SCALE-RM
scale_spnudge.F90
Go to the documentation of this file.
1 #include "scalelib.h"
3  !-----------------------------------------------------------------------------
4  !
5  !++ used modules
6  !
8  use scale_io
9  use scale_prc
10 
11  !-----------------------------------------------------------------------------
12  implicit none
13  private
14  !-----------------------------------------------------------------------------
15  !
16  !++ Public procedure
17  !
18  public :: spnudge_setup
19  public :: spnudge_finalize
20 
21  !-----------------------------------------------------------------------------
22  !
23  !++ Public variables
24  !
25  logical, public :: spnudge_uv = .false.
26  logical, public :: spnudge_uv_divfree = .false.
27  integer, public :: spnudge_uv_lm = 3
28  integer, public :: spnudge_uv_mm = 3
29 
30  logical, public :: spnudge_pt = .false.
31  integer, public :: spnudge_pt_lm = 3
32  integer, public :: spnudge_pt_mm = 3
33 
34  logical, public :: spnudge_qv = .false.
35  integer, public :: spnudge_qv_lm = 3
36  integer, public :: spnudge_qv_mm = 3
37 
38  real(rp), allocatable, public :: spnudge_u_alpha(:,:,:)
39  real(rp), allocatable, public :: spnudge_v_alpha(:,:,:)
40  real(rp), allocatable, public :: spnudge_pt_alpha(:,:,:)
41  real(rp), allocatable, public :: spnudge_qv_alpha(:,:,:)
42 
43  !-----------------------------------------------------------------------------
44  !
45  !++ Private variables
46  !
47 
48 contains
49 
50  subroutine spnudge_setup(KA, KS, KE, IA, IS, IE, JA, JS, JE)
51  use scale_dft, only: &
52  dft_setup
54  real_cz => atmos_grid_cartesc_real_cz, &
55  real_czuy => atmos_grid_cartesc_real_czuy, &
56  real_czxv => atmos_grid_cartesc_real_czxv
57  implicit none
58  integer, intent(in) :: ka, ks, ke
59  integer, intent(in) :: ia, is, ie
60  integer, intent(in) :: ja, js, je
61 
62  real(rp) :: spnudge_uv_tau = 0.0_rp
63  real(rp) :: spnudge_pt_tau = 0.0_rp
64  real(rp) :: spnudge_qv_tau = 0.0_rp
65 
66  real(rp) :: spnudge_level1 = 0.0_rp
67  real(rp) :: spnudge_level2 = 0.0_rp
68  real(rp) :: spnudge_level3 = 1e10_rp
69  real(rp) :: spnudge_level4 = 1e10_rp
70 
71  namelist /param_spnudge/ &
72  spnudge_uv, &
74  spnudge_uv_lm, &
75  spnudge_uv_mm, &
76  spnudge_uv_tau, &
77  spnudge_pt, &
78  spnudge_pt_lm, &
79  spnudge_pt_mm, &
80  spnudge_pt_tau, &
81  spnudge_qv, &
82  spnudge_qv_lm, &
83  spnudge_qv_mm, &
84  spnudge_qv_tau, &
85  spnudge_level1, &
86  spnudge_level2, &
87  spnudge_level3, &
88  spnudge_level4
89 
90  real(rp) :: uv_alpha, pt_alpha, qv_alpha
91 
92 
93  integer :: k, i, j
94  integer :: ierr
95  !---------------------------------------------------------------------------
96 
97  log_newline
98  log_info("SPNUDGE_setup",*) 'Setup'
99 
100  !--- read namelist
101  rewind(io_fid_conf)
102  read(io_fid_conf,nml=param_spnudge,iostat=ierr)
103  if( ierr < 0 ) then !--- missing
104  log_info("SPNUDGE_setup",*) 'Not found namelist. Default used.'
105  elseif( ierr > 0 ) then !--- fatal error
106  log_error("SPNUDGE_setup",*) 'Not appropriate names in namelist PARAM_SPNUDGE. Check!'
107  call prc_abort
108  endif
109  log_nml(param_spnudge)
110 
111  if ( spnudge_level1 > spnudge_level2 ) then
112  log_error("SPNUDGE_setup",*) 'SPNUDGE_level1 must be lowere or equal to SPNUDGE_level2'
113  call prc_abort
114  end if
115  if ( spnudge_level2 > spnudge_level3 ) then
116  log_error("SPNUDGE_setup",*) 'SPNUDGE_level2 must be lowere or equal to SPNUDGE_level3'
117  call prc_abort
118  end if
119  if ( spnudge_level3 > spnudge_level4 ) then
120  log_error("SPNUDGE_setup",*) 'SPNUDGE_level3 must be lowere or equal to SPNUDGE_level4'
121  call prc_abort
122  end if
123 
124  if ( spnudge_uv .or. spnudge_pt .or. spnudge_qv ) then
125  log_warn("SPNUDGE_setup",*) 'Spectrul nudging is still experimental'
126  end if
127 
128  allocate( spnudge_u_alpha(ka,ia,ja) )
129  allocate( spnudge_v_alpha(ka,ia,ja) )
130  allocate( spnudge_pt_alpha(ka,ia,ja) )
131  allocate( spnudge_qv_alpha(ka,ia,ja) )
132 
133  if ( spnudge_uv .and. spnudge_uv_tau > 0.0_rp ) then
134  uv_alpha = 1.0_rp / spnudge_uv_tau
135 
136  !$omp parallel do
137  do j = js, je
138  do i = is, ie
139  do k = ks, ke
140  if ( real_czuy(k,i,j) < spnudge_level1 ) then
141  spnudge_u_alpha(k,i,j) = 0.0_rp
142  elseif ( real_czuy(k,i,j) < spnudge_level2 ) then
143  spnudge_u_alpha(k,i,j) = ( real_czuy(k,i,j) - spnudge_level1 ) / ( spnudge_level2 - spnudge_level1 ) * uv_alpha
144  elseif ( real_czuy(k,i,j) < spnudge_level3 ) then
145  spnudge_u_alpha(k,i,j) = uv_alpha
146  elseif ( real_czuy(k,i,j) < spnudge_level4 ) then
147  spnudge_u_alpha(k,i,j) = ( real_czuy(k,i,j) - spnudge_level3 ) / ( spnudge_level4 - spnudge_level3 ) * uv_alpha
148  else
149  spnudge_u_alpha(k,i,j) = 0.0_rp
150  endif
151  enddo
152  enddo
153  enddo
154 
155  !$omp parallel do
156  do j = js, je
157  do i = is, ie
158  do k = ks, ke
159  if ( real_czxv(k,i,j) < spnudge_level1 ) then
160  spnudge_v_alpha(k,i,j) = 0.0_rp
161  elseif ( real_czxv(k,i,j) < spnudge_level2 ) then
162  spnudge_v_alpha(k,i,j) = ( real_czxv(k,i,j) - spnudge_level1 ) / ( spnudge_level2 - spnudge_level1 ) * uv_alpha
163  elseif ( real_czxv(k,i,j) < spnudge_level3 ) then
164  spnudge_v_alpha(k,i,j) = uv_alpha
165  elseif ( real_czxv(k,i,j) < spnudge_level4 ) then
166  spnudge_v_alpha(k,i,j) = ( real_czxv(k,i,j) - spnudge_level3 ) / ( spnudge_level4 - spnudge_level3 ) * uv_alpha
167  else
168  spnudge_v_alpha(k,i,j) = 0.0_rp
169  endif
170  enddo
171  enddo
172  enddo
173 
174  else
175 
176  !$omp parallel do
177  do j = js, je
178  do i = is, ie
179  do k = ks, ke
180  spnudge_u_alpha(k,i,j) = 0.0_rp
181  spnudge_v_alpha(k,i,j) = 0.0_rp
182  end do
183  end do
184  end do
185 
186  endif
187 
188  if ( spnudge_pt .and. spnudge_pt_tau > 0.0_rp ) then
189  pt_alpha = 1.0_rp / spnudge_pt_tau
190 
191  !$omp parallel do
192  do j = js, je
193  do i = is, ie
194  do k = ks, ke
195  if ( real_cz(k,i,j) < spnudge_level1 ) then
196  spnudge_pt_alpha(k,i,j) = 0.0_rp
197  elseif ( real_cz(k,i,j) < spnudge_level2 ) then
198  spnudge_pt_alpha(k,i,j) = ( real_cz(k,i,j) - spnudge_level1 ) / ( spnudge_level2 - spnudge_level1 ) * pt_alpha
199  elseif ( real_cz(k,i,j) < spnudge_level3 ) then
200  spnudge_pt_alpha(k,i,j) = pt_alpha
201  elseif ( real_cz(k,i,j) < spnudge_level4 ) then
202  spnudge_pt_alpha(k,i,j) = ( real_cz(k,i,j) - spnudge_level3 ) / ( spnudge_level4 - spnudge_level3 ) * pt_alpha
203  else
204  spnudge_pt_alpha(k,i,j) = 0.0_rp
205  endif
206  enddo
207  enddo
208  enddo
209 
210  else
211 
212  !$omp parallel do
213  do j = js, je
214  do i = is, ie
215  do k = ks, ke
216  spnudge_pt_alpha(k,i,j) = 0.0_rp
217  end do
218  end do
219  end do
220 
221  endif
222 
223  if ( spnudge_qv .and. spnudge_qv_tau > 0.0_rp ) then
224  qv_alpha = 1.0_rp / spnudge_qv_tau
225 
226  !$omp parallel do
227  do j = js, je
228  do i = is, ie
229  do k = ks, ke
230  if ( real_cz(k,i,j) < spnudge_level1 ) then
231  spnudge_qv_alpha(k,i,j) = 0.0_rp
232  elseif ( real_cz(k,i,j) < spnudge_level2 ) then
233  spnudge_qv_alpha(k,i,j) = ( real_cz(k,i,j) - spnudge_level1 ) / ( spnudge_level2 - spnudge_level1 ) * qv_alpha
234  elseif ( real_cz(k,i,j) < spnudge_level3 ) then
235  spnudge_qv_alpha(k,i,j) = qv_alpha
236  elseif ( real_cz(k,i,j) < spnudge_level4 ) then
237  spnudge_qv_alpha(k,i,j) = ( real_cz(k,i,j) - spnudge_level3 ) / ( spnudge_level4 - spnudge_level3 ) * qv_alpha
238  else
239  spnudge_qv_alpha(k,i,j) = 0.0_rp
240  endif
241  enddo
242  enddo
243  enddo
244 
245  else
246 
247  !$omp parallel do
248  do j = js, je
249  do i = is, ie
250  do k = ks, ke
251  spnudge_qv_alpha(k,i,j) = 0.0_rp
252  end do
253  end do
254  end do
255 
256  end if
257 
258  !$acc enter data copyin(SPNUDGE_u_alpha, SPNUDGE_v_alpha, SPNUDGE_pt_alpha, SPNUDGE_qv_alpha)
259 
260  call dft_setup( ka, ks, ke, ia, is, ie, ja, js, je, &
263 
264  return
265  end subroutine spnudge_setup
266 
267  subroutine spnudge_finalize
268  use scale_dft, only: &
270 
271  call dft_finalize
272 
273  !$acc exit data delete(SPNUDGE_u_alpha, SPNUDGE_v_alpha, SPNUDGE_pt_alpha, SPNUDGE_qv_alpha)
274  deallocate( spnudge_u_alpha )
275  deallocate( spnudge_v_alpha )
276  deallocate( spnudge_pt_alpha )
277  deallocate( spnudge_qv_alpha )
278 
279  return
280  end subroutine spnudge_finalize
281 
282 end module scale_spnudge
scale_spnudge::spnudge_setup
subroutine, public spnudge_setup(KA, KS, KE, IA, IS, IE, JA, JS, JE)
Definition: scale_spnudge.F90:51
scale_dft::dft_finalize
subroutine, public dft_finalize
Definition: scale_dft.F90:102
scale_prc::prc_abort
subroutine, public prc_abort
Abort Process.
Definition: scale_prc.F90:350
scale_spnudge::spnudge_uv_lm
integer, public spnudge_uv_lm
Definition: scale_spnudge.F90:27
scale_atmos_grid_cartesc_real::atmos_grid_cartesc_real_cz
real(rp), dimension(:,:,:), allocatable, public atmos_grid_cartesc_real_cz
geopotential height [m] (zxy)
Definition: scale_atmos_grid_cartesC_real.F90:39
scale_spnudge::spnudge_pt_lm
integer, public spnudge_pt_lm
Definition: scale_spnudge.F90:31
scale_spnudge::spnudge_pt
logical, public spnudge_pt
Definition: scale_spnudge.F90:30
scale_spnudge::spnudge_pt_alpha
real(rp), dimension(:,:,:), allocatable, public spnudge_pt_alpha
Definition: scale_spnudge.F90:40
scale_precision
module PRECISION
Definition: scale_precision.F90:14
scale_spnudge::spnudge_uv_divfree
logical, public spnudge_uv_divfree
Definition: scale_spnudge.F90:26
scale_atmos_grid_cartesc_real
module Atmosphere GRID CartesC Real(real space)
Definition: scale_atmos_grid_cartesC_real.F90:11
scale_spnudge::spnudge_qv_lm
integer, public spnudge_qv_lm
Definition: scale_spnudge.F90:35
scale_atmos_grid_cartesc_real::atmos_grid_cartesc_real_czxv
real(rp), dimension(:,:,:), allocatable, public atmos_grid_cartesc_real_czxv
geopotential height [m] (zxv)
Definition: scale_atmos_grid_cartesC_real.F90:41
scale_spnudge::spnudge_qv
logical, public spnudge_qv
Definition: scale_spnudge.F90:34
scale_dft
Definition: scale_dft.F90:3
scale_prc
module PROCESS
Definition: scale_prc.F90:11
scale_spnudge::spnudge_pt_mm
integer, public spnudge_pt_mm
Definition: scale_spnudge.F90:32
scale_precision::rp
integer, parameter, public rp
Definition: scale_precision.F90:41
scale_io
module STDIO
Definition: scale_io.F90:10
scale_spnudge::spnudge_u_alpha
real(rp), dimension(:,:,:), allocatable, public spnudge_u_alpha
Definition: scale_spnudge.F90:38
scale_spnudge::spnudge_finalize
subroutine, public spnudge_finalize
Definition: scale_spnudge.F90:268
scale_dft::dft_setup
subroutine, public dft_setup(KA, KS, KE, IA, IS, IE, JA, JS, JE, LM, MM)
Definition: scale_dft.F90:37
scale_spnudge::spnudge_qv_mm
integer, public spnudge_qv_mm
Definition: scale_spnudge.F90:36
scale_spnudge::spnudge_uv_mm
integer, public spnudge_uv_mm
Definition: scale_spnudge.F90:28
scale_spnudge
Definition: scale_spnudge.F90:2
scale_spnudge::spnudge_qv_alpha
real(rp), dimension(:,:,:), allocatable, public spnudge_qv_alpha
Definition: scale_spnudge.F90:41
scale_io::io_fid_conf
integer, public io_fid_conf
Config file ID.
Definition: scale_io.F90:57
scale_spnudge::spnudge_uv
logical, public spnudge_uv
Definition: scale_spnudge.F90:25
scale_spnudge::spnudge_v_alpha
real(rp), dimension(:,:,:), allocatable, public spnudge_v_alpha
Definition: scale_spnudge.F90:39
scale_atmos_grid_cartesc_real::atmos_grid_cartesc_real_czuy
real(rp), dimension(:,:,:), allocatable, public atmos_grid_cartesc_real_czuy
geopotential height [m] (zuy)
Definition: scale_atmos_grid_cartesC_real.F90:40