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

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

last commit documented

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