source: palm/trunk/SOURCE/subsidence.f90 @ 1729

Last change on this file since 1729 was 1729, checked in by gronemeier, 8 years ago

bugfix for subsidence in combination with Rayleigh damping

  • Property svn:keywords set to Id
File size: 13.2 KB
Line 
1!> @file subsidence.f90
2!--------------------------------------------------------------------------------!
3! This file is part of PALM.
4!
5! PALM is free software: you can redistribute it and/or modify it under the terms
6! of the GNU General Public License as published by the Free Software Foundation,
7! either version 3 of the License, or (at your option) any later version.
8!
9! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
10! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12!
13! You should have received a copy of the GNU General Public License along with
14! PALM. If not, see <http://www.gnu.org/licenses/>.
15!
16! Copyright 1997-2014 Leibniz Universitaet Hannover
17!--------------------------------------------------------------------------------!
18!
19! Current revisions:
20! -----------------
21! Bugfix: shifting of initial profiles only once each time step
22!
23! Former revisions:
24! -----------------
25! $Id: subsidence.f90 1729 2015-11-20 11:01:48Z gronemeier $
26!
27! 1682 2015-10-07 23:56:08Z knoop
28! Code annotations made doxygen readable
29!
30! 1489 2014-10-30 08:09:12Z raasch
31! bugfix: sums_ls_l can only be used if large_scale_forcing is switched on
32!
33! 1382 2014-04-30 12:15:41Z boeske
34! Changed the weighting factor that is used in the summation of subsidence
35! tendencies for profile data output from weight_pres to weight_substep
36! added Neumann boundary conditions for profile data output of subsidence terms
37! at nzt+1
38!
39! 1380 2014-04-28 12:40:45Z heinze
40! Shifting only necessary in case of scalar Rayleigh damping
41!
42! 1365 2014-04-22 15:03:56Z boeske
43! Summation of subsidence tendencies for data output added
44! +ls_index, sums_ls_l, tmp_tend
45!
46! 1353 2014-04-08 15:21:23Z heinze
47! REAL constants provided with KIND-attribute
48!
49! 1320 2014-03-20 08:40:49Z raasch
50! ONLY-attribute added to USE-statements,
51! kind-parameters added to all INTEGER and REAL declaration statements,
52! kinds are defined in new module kinds,
53! old module precision_kind is removed,
54! revision history before 2012 removed,
55! comment fields (!:) to be used for variable explanations added to
56! all variable declaration statements
57!
58! 1036 2012-10-22 13:43:42Z raasch
59! code put under GPL (PALM 3.9)
60!
61! Revision 3.7 2009-12-11 14:15:58Z heinze
62! Initial revision
63!
64! Description:
65! ------------
66!> Impact of large-scale subsidence or ascent as tendency term for use
67!> in the prognostic equation of potential temperature. This enables the
68!> construction of a constant boundary layer height z_i with time.
69!-----------------------------------------------------------------------------!
70 MODULE subsidence_mod
71 
72
73
74    IMPLICIT NONE
75
76    PRIVATE
77    PUBLIC  init_w_subsidence, subsidence
78
79    INTERFACE init_w_subsidence
80       MODULE PROCEDURE init_w_subsidence
81    END INTERFACE init_w_subsidence
82
83    INTERFACE subsidence
84       MODULE PROCEDURE subsidence
85       MODULE PROCEDURE subsidence_ij
86    END INTERFACE subsidence
87
88 CONTAINS
89
90!------------------------------------------------------------------------------!
91! Description:
92! ------------
93!> @todo Missing subroutine description.
94!------------------------------------------------------------------------------!
95    SUBROUTINE init_w_subsidence 
96
97       USE arrays_3d,                                                          &
98           ONLY:  dzu, w_subs, zu
99
100       USE control_parameters,                                                 &
101           ONLY:  message_string, ocean, subs_vertical_gradient,               &
102                  subs_vertical_gradient_level, subs_vertical_gradient_level_i
103
104       USE indices,                                                            &
105           ONLY:  nzb, nzt
106
107       USE kinds
108
109       IMPLICIT NONE
110
111       INTEGER(iwp) ::  i !<
112       INTEGER(iwp) ::  k !<
113
114       REAL(wp)     ::  gradient   !<
115       REAL(wp)     ::  ws_surface !<
116
117       IF ( .NOT. ALLOCATED( w_subs ))  THEN
118          ALLOCATE( w_subs(nzb:nzt+1) )
119          w_subs = 0.0_wp
120       ENDIF
121
122       IF ( ocean )  THEN
123          message_string = 'Applying large scale vertical motion is not ' // &
124                           'allowed for ocean runs'
125          CALL message( 'init_w_subsidence', 'PA0324', 2, 2, 0, 6, 0 )
126       ENDIF
127
128!
129!--   Compute the profile of the subsidence/ascent velocity
130!--   using the given gradients
131      i = 1
132      gradient = 0.0_wp
133      ws_surface = 0.0_wp
134     
135
136      subs_vertical_gradient_level_i(1) = 0
137      DO  k = 1, nzt+1
138         IF ( i < 11 )  THEN
139            IF ( subs_vertical_gradient_level(i) < zu(k)  .AND. &
140                 subs_vertical_gradient_level(i) >= 0.0_wp )  THEN
141               gradient = subs_vertical_gradient(i) / 100.0_wp
142               subs_vertical_gradient_level_i(i) = k - 1
143               i = i + 1
144            ENDIF
145         ENDIF
146         IF ( gradient /= 0.0_wp )  THEN
147            IF ( k /= 1 )  THEN
148               w_subs(k) = w_subs(k-1) + dzu(k) * gradient
149            ELSE
150               w_subs(k) = ws_surface   + 0.5_wp * dzu(k) * gradient
151            ENDIF
152         ELSE
153            w_subs(k) = w_subs(k-1)
154         ENDIF
155      ENDDO
156
157!
158!--   In case of no given gradients for the subsidence/ascent velocity,
159!--   choose zero gradient
160      IF ( subs_vertical_gradient_level(1) == -9999999.9_wp )  THEN
161         subs_vertical_gradient_level(1) = 0.0_wp
162      ENDIF
163
164    END SUBROUTINE init_w_subsidence
165
166
167!------------------------------------------------------------------------------!
168! Description:
169! ------------
170!> @todo Missing subroutine description.
171!------------------------------------------------------------------------------!
172    SUBROUTINE subsidence( tendency, var, var_init, ls_index ) 
173
174       USE arrays_3d,                                                          &
175           ONLY:  ddzu, w_subs
176
177       USE control_parameters,                                                 &
178           ONLY:  dt_3d, intermediate_timestep_count, large_scale_forcing,     &
179                  scalar_rayleigh_damping
180
181       USE indices,                                                            &
182           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzb_s_inner,&
183                  nzt
184
185       USE kinds
186
187       USE statistics,                                                         &
188           ONLY:  sums_ls_l, weight_substep
189
190       IMPLICIT NONE
191 
192       INTEGER(iwp) ::  i !<
193       INTEGER(iwp) ::  j !<
194       INTEGER(iwp) ::  k !<
195       INTEGER(iwp) ::  ls_index !<
196
197       REAL(wp)     ::  tmp_tend !<
198       REAL(wp)     ::  tmp_grad !<
199   
200       REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  var      !<
201       REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  tendency !<
202       REAL(wp), DIMENSION(nzb:nzt+1) ::  var_init                     !<
203       REAL(wp), DIMENSION(nzb:nzt+1) ::  var_mod                      !<
204
205       var_mod = var_init
206
207!
208!--    Influence of w_subsidence on the current tendency term
209       DO  i = nxl, nxr
210          DO  j = nys, nyn
211
212             DO  k = nzb_s_inner(j,i)+1, nzt 
213                IF ( w_subs(k) < 0.0_wp )  THEN    ! large-scale subsidence
214                   tmp_tend = - w_subs(k) *                                    &
215                              ( var(k+1,j,i) - var(k,j,i) ) * ddzu(k+1)
216                ELSE                               ! large-scale ascent
217                   tmp_tend = - w_subs(k) *                                    &
218                              ( var(k,j,i) - var(k-1,j,i) ) * ddzu(k)
219                ENDIF
220
221                tendency(k,j,i) = tendency(k,j,i) + tmp_tend
222
223                IF ( large_scale_forcing )  THEN
224                   sums_ls_l(k,ls_index) = sums_ls_l(k,ls_index) + tmp_tend    &
225                                   * weight_substep(intermediate_timestep_count)
226                ENDIF
227             ENDDO
228
229             sums_ls_l(nzt+1,ls_index) = sums_ls_l(nzt,ls_index)
230
231          ENDDO
232       ENDDO
233
234!
235!--    Shifting of the initial profile is especially necessary with Rayleigh
236!--    damping switched on
237       IF ( scalar_rayleigh_damping .AND.                                      &
238            intermediate_timestep_count == 1 )  THEN
239          DO  k = nzb, nzt
240             IF ( w_subs(k) < 0.0_wp )  THEN      ! large-scale subsidence
241                var_mod(k) = var_init(k) - dt_3d * w_subs(k) *  &
242                                  ( var_init(k+1) - var_init(k) ) * ddzu(k+1)
243             ENDIF
244          ENDDO
245!
246!--      At the upper boundary, the initial profile is shifted with aid of
247!--      the gradient tmp_grad. (This is ok if the gradients are linear.)
248         IF ( w_subs(nzt) < 0.0_wp )  THEN
249            tmp_grad = ( var_init(nzt+1) - var_init(nzt) ) * ddzu(nzt+1)
250            var_mod(nzt+1) = var_init(nzt+1) -  &
251                                 dt_3d * w_subs(nzt+1) * tmp_grad
252         ENDIF
253       
254
255         DO  k = nzt+1, nzb+1, -1
256            IF ( w_subs(k) >= 0.0_wp )  THEN  ! large-scale ascent
257               var_mod(k) = var_init(k) - dt_3d * w_subs(k) *  &
258                                  ( var_init(k) - var_init(k-1) ) * ddzu(k) 
259            ENDIF
260         ENDDO
261!
262!--      At the lower boundary shifting is not necessary because the
263!--      subsidence velocity w_subs(nzb) vanishes.
264         IF ( w_subs(nzb+1) >= 0.0_wp )  THEN
265            var_mod(nzb) = var_init(nzb)
266         ENDIF
267
268         var_init = var_mod
269      ENDIF
270
271
272 END SUBROUTINE subsidence
273
274!------------------------------------------------------------------------------!
275! Description:
276! ------------
277!> @todo Missing subroutine description.
278!------------------------------------------------------------------------------!
279 SUBROUTINE subsidence_ij( i, j, tendency, var, var_init, ls_index ) 
280
281       USE arrays_3d,                                                          &
282           ONLY:  ddzu, w_subs
283
284       USE control_parameters,                                                 &
285           ONLY:  dt_3d, intermediate_timestep_count, large_scale_forcing,     &
286                  scalar_rayleigh_damping
287
288       USE indices,                                                            &
289           ONLY:  nxl, nxlg, nxrg, nyng, nys, nysg, nzb_s_inner, nzb, nzt
290
291       USE kinds
292
293       USE statistics,                                                         &
294           ONLY:  sums_ls_l, weight_substep
295
296       IMPLICIT NONE
297 
298       INTEGER(iwp) ::  i !<
299       INTEGER(iwp) ::  j !<
300       INTEGER(iwp) ::  k !<
301       INTEGER(iwp) ::  ls_index !<
302
303       REAL(wp)     ::  tmp_tend !<
304       REAL(wp)     ::  tmp_grad !<
305   
306       REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  var      !<
307       REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  tendency !<
308       REAL(wp), DIMENSION(nzb:nzt+1) ::  var_init                     !<
309       REAL(wp), DIMENSION(nzb:nzt+1) ::  var_mod                      !<
310
311       var_mod = var_init
312
313!
314!--    Influence of w_subsidence on the current tendency term
315       DO  k = nzb_s_inner(j,i)+1, nzt 
316          IF ( w_subs(k) < 0.0_wp )  THEN      ! large-scale subsidence
317             tmp_tend = - w_subs(k) * ( var(k+1,j,i) - var(k,j,i) ) * ddzu(k+1)
318          ELSE                                 ! large-scale ascent
319             tmp_tend = - w_subs(k) * ( var(k,j,i) - var(k-1,j,i) ) * ddzu(k)
320          ENDIF
321
322          tendency(k,j,i) = tendency(k,j,i) + tmp_tend
323
324          IF ( large_scale_forcing )  THEN
325             sums_ls_l(k,ls_index) = sums_ls_l(k,ls_index) + tmp_tend          &
326                                   * weight_substep(intermediate_timestep_count)
327          ENDIF
328       ENDDO
329
330       IF ( large_scale_forcing )  THEN
331          sums_ls_l(nzt+1,ls_index) = sums_ls_l(nzt,ls_index)
332       ENDIF
333
334!
335!--    Shifting of the initial profile is especially necessary with Rayleigh
336!--    damping switched on
337       IF ( scalar_rayleigh_damping .AND.                                      &
338            intermediate_timestep_count == 1 )  THEN
339          IF ( i == nxl .AND. j == nys )  THEN ! shifting only once per PE
340
341             DO  k = nzb, nzt
342                IF ( w_subs(k) < 0.0_wp )  THEN      ! large-scale subsidence
343                   var_mod(k) = var_init(k) - dt_3d * w_subs(k) *  &
344                                     ( var_init(k+1) - var_init(k) ) * ddzu(k+1)
345                ENDIF
346             ENDDO
347!
348!--          At the upper boundary, the initial profile is shifted with aid of
349!--          the gradient tmp_grad. (This is ok if the gradients are linear.)
350             IF ( w_subs(nzt) < 0.0_wp )  THEN
351                tmp_grad = ( var_init(nzt+1) - var_init(nzt) ) * ddzu(nzt+1)
352                var_mod(nzt+1) = var_init(nzt+1) -  &
353                                     dt_3d * w_subs(nzt+1) * tmp_grad
354             ENDIF
355       
356
357             DO  k = nzt+1, nzb+1, -1
358                IF ( w_subs(k) >= 0.0_wp )  THEN  ! large-scale ascent
359                   var_mod(k) = var_init(k) - dt_3d * w_subs(k) *  &
360                                      ( var_init(k) - var_init(k-1) ) * ddzu(k)
361                ENDIF
362             ENDDO
363!
364!--          At the lower boundary shifting is not necessary because the
365!--          subsidence velocity w_subs(nzb) vanishes.
366             IF ( w_subs(nzb+1) >= 0.0_wp )  THEN
367                var_mod(nzb) = var_init(nzb)
368             ENDIF
369
370             var_init = var_mod 
371
372          ENDIF
373       ENDIF
374
375 END SUBROUTINE subsidence_ij
376
377
378 END MODULE subsidence_mod
Note: See TracBrowser for help on using the repository browser.