source: palm/trunk/SOURCE/prandtl_fluxes.f90 @ 1494

Last change on this file since 1494 was 1494, checked in by maronga, 9 years ago

Minor bugfixes in prandtl_fluxes.f90

  • Property svn:keywords set to Id
File size: 18.7 KB
Line 
1 SUBROUTINE prandtl_fluxes
2
3!--------------------------------------------------------------------------------!
4! This file is part of PALM.
5!
6! PALM is free software: you can redistribute it and/or modify it under the terms
7! of the GNU General Public License as published by the Free Software Foundation,
8! either version 3 of the License, or (at your option) any later version.
9!
10! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13!
14! You should have received a copy of the GNU General Public License along with
15! PALM. If not, see <http://www.gnu.org/licenses/>.
16!
17! Copyright 1997-2014 Leibniz Universitaet Hannover
18!--------------------------------------------------------------------------------!
19!
20! Current revisions:
21! -----------------
22! Bugfixes: qs is now calculated before calculation of Rif. Ccalculation of
23! buoyancy flux in Rif corrected (added missing humidity term), allow use of
24! topography for coupled runs (not tested)
25!
26! Former revisions:
27! -----------------
28! $Id: prandtl_fluxes.f90 1494 2014-11-21 17:14:03Z maronga $
29!
30! 1361 2014-04-16 15:17:48Z hoffmann
31! Bugfix: calculation of turbulent fluxes of rain water content (qrsws) and rain
32! drop concentration (nrsws) added
33!
34! 1340 2014-03-25 19:45:13Z kanani
35! REAL constants defined as wp-kind
36!
37! 1320 2014-03-20 08:40:49Z raasch
38! ONLY-attribute added to USE-statements,
39! kind-parameters added to all INTEGER and REAL declaration statements,
40! kinds are defined in new module kinds,
41! old module precision_kind is removed,
42! revision history before 2012 removed,
43! comment fields (!:) to be used for variable explanations added to
44! all variable declaration statements
45!
46! 1276 2014-01-15 13:40:41Z heinze
47! Use LSF_DATA also in case of Dirichlet bottom boundary condition for scalars
48!
49! 1257 2013-11-08 15:18:40Z raasch
50! openACC "kernels do" replaced by "kernels loop", "loop independent" added
51!
52! 1036 2012-10-22 13:43:42Z raasch
53! code put under GPL (PALM 3.9)
54!
55! 1015 2012-09-27 09:23:24Z raasch
56! OpenACC statements added
57!
58! 978 2012-08-09 08:28:32Z fricke
59! roughness length for scalar quantities z0h added
60!
61! Revision 1.1  1998/01/23 10:06:06  raasch
62! Initial revision
63!
64!
65! Description:
66! ------------
67! Diagnostic computation of vertical fluxes in the Prandtl layer from the
68! values of the variables at grid point k=1
69!------------------------------------------------------------------------------!
70
71    USE arrays_3d,                                                             &
72        ONLY:  e, nr, nrs, nrsws, pt, q, qr, qrs, qrsws, qs, qsws, rif, shf,   &
73               ts, u, us, usws, v, vpt, vsws, zu, zw, z0, z0h
74
75    USE control_parameters,                                                    &
76        ONLY:  cloud_physics, constant_heatflux, constant_waterflux,           &
77               coupling_mode, g, humidity, ibc_e_b, icloud_scheme, kappa,      &
78               large_scale_forcing, lsf_surf, passive_scalar, precipitation,   &
79               pt_surface, q_surface, rif_max, rif_min, run_coupled,           &
80               surface_pressure
81
82    USE indices,                                                               &
83        ONLY:  nxl, nxlg, nxr, nxrg, nys, nysg, nyn, nyng, nzb_s_inner,        &
84               nzb_u_inner, nzb_v_inner
85
86    USE kinds
87
88    IMPLICIT NONE
89
90    INTEGER(iwp) ::  i            !:
91    INTEGER(iwp) ::  j            !:
92    INTEGER(iwp) ::  k            !:
93
94    LOGICAL      ::  coupled_run  !:
95
96    REAL(wp)     ::  a            !:
97    REAL(wp)     ::  b            !:
98    REAL(wp)     ::  e_q          !:
99    REAL(wp)     ::  rifm         !:
100    REAL(wp)     ::  uv_total     !:
101    REAL(wp)     ::  z_p          !:
102
103!
104!-- Data information for accelerators
105    !$acc data present( e, nrsws, nzb_u_inner, nzb_v_inner, nzb_s_inner, pt )  &
106    !$acc      present( q, qs, qsws, qrsws, rif, shf, ts, u, us, usws, v )     &
107    !$acc      present( vpt, vsws, zu, zw, z0, z0h )
108!
109!-- Compute theta*
110    IF ( constant_heatflux )  THEN
111!
112!--    For a given heat flux in the Prandtl layer:
113!--    for u* use the value from the previous time step
114       !$OMP PARALLEL DO
115       !$acc kernels loop
116       DO  i = nxlg, nxrg
117          DO  j = nysg, nyng
118             ts(j,i) = -shf(j,i) / ( us(j,i) + 1E-30_wp )
119!
120!--          ts must be limited, because otherwise overflow may occur in case of
121!--          us=0 when computing rif further below
122             IF ( ts(j,i) < -1.05E5_wp )  ts(j,i) = -1.0E5_wp
123             IF ( ts(j,i) >   1.0E5_wp )  ts(j,i) =  1.0E5_wp
124          ENDDO
125       ENDDO
126
127    ELSE
128!
129!--    For a given surface temperature:
130!--    (the Richardson number is still the one from the previous time step)
131   
132       IF ( large_scale_forcing .AND. lsf_surf )  THEN
133          pt(nzb_s_inner(j,i),:,:) = pt_surface
134       ENDIF
135
136       !$OMP PARALLEL DO PRIVATE( a, b, k, z_p )
137       !$acc kernels loop
138       DO  i = nxlg, nxrg
139          DO  j = nysg, nyng
140
141             k   = nzb_s_inner(j,i)
142             z_p = zu(k+1) - zw(k)
143
144             IF ( rif(j,i) >= 0.0_wp )  THEN
145!
146!--             Stable stratification
147                ts(j,i) = kappa * ( pt(k+1,j,i) - pt(k,j,i) ) / (           &
148                                  LOG( z_p / z0h(j,i) ) +                   &
149                                  5.0_wp * rif(j,i) * ( z_p - z0h(j,i) ) / z_p &
150                                                                )
151             ELSE
152!
153!--             Unstable stratification
154                a = SQRT( 1.0_wp - 16.0_wp * rif(j,i) )
155                b = SQRT( 1.0_wp - 16.0_wp * rif(j,i) * z0h(j,i) / z_p )
156
157                ts(j,i) = kappa * ( pt(k+1,j,i) - pt(k,j,i) ) /  (             &
158                          LOG( z_p / z0h(j,i) ) -                              &
159                          2.0_wp * LOG( ( 1.0_wp + a ) / ( 1.0_wp + b ) ) )
160             ENDIF
161
162          ENDDO
163       ENDDO
164    ENDIF
165
166!
167!-- If required compute q*
168    IF ( humidity  .OR.  passive_scalar )  THEN
169       IF ( constant_waterflux )  THEN
170!
171!--       For a given water flux in the Prandtl layer:
172          !$OMP PARALLEL DO
173          !$acc kernels loop
174          DO  i = nxlg, nxrg
175             DO  j = nysg, nyng
176                qs(j,i) = -qsws(j,i) / ( us(j,i) + 1E-30_wp )
177             ENDDO
178          ENDDO
179         
180       ELSE
181          coupled_run = ( coupling_mode == 'atmosphere_to_ocean' .AND. run_coupled )
182
183           IF ( large_scale_forcing .AND. lsf_surf )  THEN
184              q(nzb_s_inner(j,i),:,:) = q_surface
185           ENDIF
186
187          !$OMP PARALLEL DO PRIVATE( a, b, k, z_p )
188          !$acc kernels loop independent
189          DO  i = nxlg, nxrg
190             !$acc loop independent
191             DO  j = nysg, nyng
192
193                k   = nzb_s_inner(j,i)
194                z_p = zu(k+1) - zw(k)
195
196!
197!--             Assume saturation for atmosphere coupled to ocean (but not
198!--             in case of precursor runs)
199                IF ( coupled_run )  THEN
200                   e_q = 6.1_wp * &
201                           EXP( 0.07_wp * ( MIN(pt(k,j,i),pt(k+1,j,i)) - 273.15_wp ) )
202                   q(k,j,i) = 0.622_wp * e_q / ( surface_pressure - e_q )
203                ENDIF
204                IF ( rif(j,i) >= 0.0_wp )  THEN
205!
206!--                Stable stratification
207                   qs(j,i) = kappa * ( q(k+1,j,i) - q(k,j,i) ) / (             &
208                                  LOG( z_p / z0h(j,i) ) +                      &
209                                  5.0_wp * rif(j,i) * ( z_p - z0h(j,i) ) / z_p &
210                                                                 )
211                ELSE
212!
213!--                Unstable stratification
214                   a = SQRT( 1.0_wp - 16.0_wp * rif(j,i) ) 
215                   b = SQRT( 1.0_wp - 16.0_wp * rif(j,i) * z0h(j,i) / z_p ) 
216 
217                   qs(j,i) = kappa * ( q(k+1,j,i) - q(k,j,i) ) /   (           &
218                             LOG( z_p / z0h(j,i) ) -                           &
219                              2.0_wp * LOG( (1.0_wp + a ) / ( 1.0_wp + b ) ) )
220                ENDIF
221
222             ENDDO
223          ENDDO
224       ENDIF
225    ENDIF
226
227!
228!-- Compute z_p/L (corresponds to the Richardson-flux number)
229    IF ( .NOT. humidity )  THEN
230       !$OMP PARALLEL DO PRIVATE( k, z_p )
231       !$acc kernels loop
232       DO  i = nxlg, nxrg
233          DO  j = nysg, nyng
234             k   = nzb_s_inner(j,i)
235             z_p = zu(k+1) - zw(k)
236             rif(j,i) = z_p * kappa * g * ts(j,i) / &
237                        ( pt(k+1,j,i) * ( us(j,i)**2 + 1E-30_wp ) )
238!
239!--          Limit the value range of the Richardson numbers.
240!--          This is necessary for very small velocities (u,v --> 0), because
241!--          the absolute value of rif can then become very large, which in
242!--          consequence would result in very large shear stresses and very
243!--          small momentum fluxes (both are generally unrealistic).
244             IF ( rif(j,i) < rif_min )  rif(j,i) = rif_min
245             IF ( rif(j,i) > rif_max )  rif(j,i) = rif_max
246          ENDDO
247       ENDDO
248    ELSE
249       !$OMP PARALLEL DO PRIVATE( k, z_p )
250       !$acc kernels loop
251       DO  i = nxlg, nxrg
252          DO  j = nysg, nyng
253             k   = nzb_s_inner(j,i)
254             z_p = zu(k+1) - zw(k)
255             rif(j,i) = z_p * kappa * g *                                      &
256                        ( ts(j,i) + 0.61_wp * pt(k+1,j,i) * qs(j,i) + 0.61_wp  &
257                          * q(k+1,j,i) * ts(j,i)) /                            &
258                        ( vpt(k+1,j,i) * ( us(j,i)**2 + 1E-30_wp ) )
259!
260!--          Limit the value range of the Richardson numbers.
261!--          This is necessary for very small velocities (u,v --> 0), because
262!--          the absolute value of rif can then become very large, which in
263!--          consequence would result in very large shear stresses and very
264!--          small momentum fluxes (both are generally unrealistic).
265             IF ( rif(j,i) < rif_min )  rif(j,i) = rif_min
266             IF ( rif(j,i) > rif_max )  rif(j,i) = rif_max
267          ENDDO
268       ENDDO       
269    ENDIF
270
271!
272!-- Compute u* at the scalars' grid points
273    !$OMP PARALLEL DO PRIVATE( a, b, k, uv_total, z_p )
274    !$acc kernels loop
275    DO  i = nxl, nxr
276       DO  j = nys, nyn
277
278          k   = nzb_s_inner(j,i)
279          z_p = zu(k+1) - zw(k)
280
281!
282!--       Compute the absolute value of the horizontal velocity
283!--       (relative to the surface)
284          uv_total = SQRT( ( 0.5_wp * ( u(k+1,j,i) + u(k+1,j,i+1)              &
285                                      - u(k,j,i)   - u(k,j,i+1) ) )**2 +       &
286                           ( 0.5_wp * ( v(k+1,j,i) + v(k+1,j+1,i)              &
287                                      - v(k,j,i)   - v(k,j+1,i) ) )**2 )   
288
289
290          IF ( rif(j,i) >= 0.0_wp )  THEN
291!
292!--          Stable stratification
293             us(j,i) = kappa * uv_total / (                                    &
294                                  LOG( z_p / z0(j,i) ) +                       &
295                                  5.0_wp * rif(j,i) * ( z_p - z0(j,i) ) / z_p  &
296                                          )
297          ELSE
298!
299!--          Unstable stratification
300             a = SQRT( SQRT( 1.0_wp - 16.0_wp * rif(j,i) ) )
301             b = SQRT( SQRT( 1.0_wp - 16.0_wp * rif(j,i) / z_p * z0(j,i) ) )
302
303             us(j,i) = kappa * uv_total / (                                    &
304                       LOG( z_p / z0(j,i) ) -                                  &
305                       LOG( ( 1.0_wp + a )**2 * ( 1.0_wp + a**2 ) / (          &
306                            ( 1.0_wp + b )**2 * ( 1.0_wp + b**2 )   ) ) +      &
307                               2.0_wp * ( ATAN( a ) - ATAN( b ) )              &
308                                           )
309          ENDIF
310       ENDDO
311    ENDDO
312
313!
314!-- Values of us at ghost point locations are needed for the evaluation of usws
315!-- and vsws.
316    !$acc update host( us )
317    CALL exchange_horiz_2d( us )
318    !$acc update device( us )
319
320!
321!-- Compute u'w' for the total model domain.
322!-- First compute the corresponding component of u* and square it.
323    !$OMP PARALLEL DO PRIVATE( a, b, k, rifm, z_p )
324    !$acc kernels loop
325    DO  i = nxl, nxr
326       DO  j = nys, nyn
327
328          k   = nzb_u_inner(j,i)
329          z_p = zu(k+1) - zw(k)
330
331!
332!--       Compute Richardson-flux number for this point
333          rifm = 0.5_wp * ( rif(j,i-1) + rif(j,i) )
334          IF ( rifm >= 0.0_wp )  THEN
335!
336!--          Stable stratification
337             usws(j,i) = kappa * ( u(k+1,j,i) - u(k,j,i) )/ (                  &
338                                     LOG( z_p / z0(j,i) ) +                    &
339                                     5.0_wp * rifm * ( z_p - z0(j,i) ) / z_p   &
340                                                            )
341          ELSE
342!
343!--          Unstable stratification
344             a = SQRT( SQRT( 1.0_wp - 16.0_wp * rifm ) )
345             b = SQRT( SQRT( 1.0_wp - 16.0_wp * rifm / z_p * z0(j,i) ) )
346
347             usws(j,i) = kappa * ( u(k+1,j,i) - u(k,j,i) ) / (                 &
348                         LOG( z_p / z0(j,i) ) -                                &
349                         LOG( (1.0_wp + a )**2 * ( 1.0_wp + a**2 ) / (         &
350                              (1.0_wp + b )**2 * ( 1.0_wp + b**2 )   ) ) +     &
351                                 2.0_wp * ( ATAN( a ) - ATAN( b ) )            &
352                                                 )
353          ENDIF
354          usws(j,i) = -usws(j,i) * 0.5_wp * ( us(j,i-1) + us(j,i) )
355       ENDDO
356    ENDDO
357
358!
359!-- Compute v'w' for the total model domain.
360!-- First compute the corresponding component of u* and square it.
361    !$OMP PARALLEL DO PRIVATE( a, b, k, rifm, z_p )
362    !$acc kernels loop
363    DO  i = nxl, nxr
364       DO  j = nys, nyn
365
366          k   = nzb_v_inner(j,i)
367          z_p = zu(k+1) - zw(k)
368
369!
370!--       Compute Richardson-flux number for this point
371          rifm = 0.5_wp * ( rif(j-1,i) + rif(j,i) )
372          IF ( rifm >= 0.0_wp )  THEN
373!
374!--          Stable stratification
375             vsws(j,i) = kappa * ( v(k+1,j,i) -  v(k,j,i) ) / (                &
376                                     LOG( z_p / z0(j,i) ) +                    &
377                                     5.0_wp * rifm * ( z_p - z0(j,i) ) / z_p   &
378                                                              )
379          ELSE
380!
381!--          Unstable stratification
382             a = SQRT( SQRT( 1.0_wp - 16.0_wp * rifm ) )
383             b = SQRT( SQRT( 1.0_wp - 16.0_wp * rifm / z_p * z0(j,i) ) )
384
385             vsws(j,i) = kappa * ( v(k+1,j,i) - v(k,j,i) ) / (                 &
386                         LOG( z_p / z0(j,i) ) -                                &
387                         LOG( (1.0_wp + a )**2 * ( 1.0_wp + a**2 ) / (         &
388                              (1.0_wp + b )**2 * ( 1.0_wp + b**2 )   ) ) +     &
389                                 2.0_wp * ( ATAN( a ) - ATAN( b ) )            &
390                                                 )
391          ENDIF
392          vsws(j,i) = -vsws(j,i) * 0.5_wp * ( us(j-1,i) + us(j,i) )
393       ENDDO
394    ENDDO
395
396!
397!-- If required compute qr* and nr*
398    IF ( cloud_physics .AND. icloud_scheme == 0 .AND. precipitation )  THEN
399
400       !$OMP PARALLEL DO PRIVATE( a, b, k, z_p )
401       !$acc kernels loop independent
402       DO  i = nxlg, nxrg
403          !$acc loop independent
404          DO  j = nysg, nyng
405
406             k   = nzb_s_inner(j,i)
407             z_p = zu(k+1) - zw(k)
408
409             IF ( rif(j,i) >= 0.0 )  THEN
410!
411!--             Stable stratification
412                qrs(j,i) = kappa * ( qr(k+1,j,i) - qr(k,j,i) ) / (             &
413                               LOG( z_p / z0h(j,i) ) +                         &
414                               5.0 * rif(j,i) * ( z_p - z0h(j,i) ) / z_p )
415                nrs(j,i) = kappa * ( nr(k+1,j,i) - nr(k,j,i) ) / (             &
416                               LOG( z_p / z0h(j,i) ) +                         &
417                               5.0 * rif(j,i) * ( z_p - z0h(j,i) ) / z_p )
418
419             ELSE
420!
421!--             Unstable stratification
422                a = SQRT( 1.0 - 16.0 * rif(j,i) ) 
423                b = SQRT( 1.0 - 16.0 * rif(j,i) * z0h(j,i) / z_p ) 
424 
425                qrs(j,i) = kappa * ( qr(k+1,j,i) - qr(k,j,i) ) /   (           &
426                          LOG( z_p / z0h(j,i) ) -                              &
427                          2.0 * LOG( (1.0 + a ) / ( 1.0 + b ) ) )
428                nrs(j,i) = kappa * ( nr(k+1,j,i) - nr(k,j,i) ) /   (           &
429                          LOG( z_p / z0h(j,i) ) -                              &
430                          2.0 * LOG( (1.0 + a ) / ( 1.0 + b ) ) )
431
432             ENDIF
433
434          ENDDO
435       ENDDO
436
437    ENDIF
438
439!
440!-- Exchange the boundaries for the momentum fluxes (only for sake of
441!-- completeness)
442    !$acc update host( usws, vsws )
443    CALL exchange_horiz_2d( usws )
444    CALL exchange_horiz_2d( vsws )
445    !$acc update device( usws, vsws )
446    IF ( humidity  .OR.  passive_scalar )  THEN
447       !$acc update host( qsws )
448       CALL exchange_horiz_2d( qsws )
449       !$acc update device( qsws )
450       IF ( cloud_physics  .AND.  icloud_scheme == 0  .AND.  &
451            precipitation )  THEN
452          !$acc update host( qrsws, nrsws )
453          CALL exchange_horiz_2d( qrsws )
454          CALL exchange_horiz_2d( nrsws )
455          !$acc update device( qrsws, nrsws )
456       ENDIF
457    ENDIF
458
459!
460!-- Compute the vertical kinematic heat flux
461    IF ( .NOT. constant_heatflux )  THEN
462       !$OMP PARALLEL DO
463       !$acc kernels loop independent
464       DO  i = nxlg, nxrg
465          !$acc loop independent
466          DO  j = nysg, nyng
467             shf(j,i) = -ts(j,i) * us(j,i)
468          ENDDO
469       ENDDO
470    ENDIF
471
472!
473!-- Compute the vertical water/scalar flux
474    IF ( .NOT. constant_waterflux .AND. ( humidity .OR. passive_scalar ) ) THEN
475       !$OMP PARALLEL DO
476       !$acc kernels loop independent
477       DO  i = nxlg, nxrg
478          !$acc loop independent
479          DO  j = nysg, nyng
480             qsws(j,i) = -qs(j,i) * us(j,i)
481          ENDDO
482       ENDDO
483    ENDIF
484
485!
486!-- Compute (turbulent) fluxes of rain water content and rain drop concentartion
487    IF ( cloud_physics  .AND.  icloud_scheme == 0  .AND.  precipitation )  THEN
488       !$OMP PARALLEL DO
489       !$acc kernels loop independent
490       DO  i = nxlg, nxrg
491          !$acc loop independent
492          DO  j = nysg, nyng
493             qrsws(j,i) = -qrs(j,i) * us(j,i)
494             nrsws(j,i) = -nrs(j,i) * us(j,i)
495          ENDDO
496       ENDDO
497    ENDIF
498
499!
500!-- Bottom boundary condition for the TKE
501    IF ( ibc_e_b == 2 )  THEN
502       !$OMP PARALLEL DO
503       !$acc kernels loop independent
504       DO  i = nxlg, nxrg
505          !$acc loop independent
506          DO  j = nysg, nyng
507             e(nzb_s_inner(j,i)+1,j,i) = ( us(j,i) / 0.1_wp )**2
508!
509!--          As a test: cm = 0.4
510!            e(nzb_s_inner(j,i)+1,j,i) = ( us(j,i) / 0.4_wp )**2
511             e(nzb_s_inner(j,i),j,i)   = e(nzb_s_inner(j,i)+1,j,i)
512          ENDDO
513       ENDDO
514    ENDIF
515
516    !$acc end data
517
518 END SUBROUTINE prandtl_fluxes
Note: See TracBrowser for help on using the repository browser.