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

Last change on this file since 1016 was 1015, checked in by raasch, 12 years ago

Starting with changes required for GPU optimization. OpenACC statements for using NVIDIA GPUs added.
Adjustment of mixing length to the Prandtl mixing length at first grid point above ground removed.
mask array is set zero for ghost boundaries

  • Property svn:keywords set to Id
File size: 13.8 KB
RevLine 
[1]1 SUBROUTINE prandtl_fluxes
2
3!------------------------------------------------------------------------------!
[484]4! Current revisions:
[1]5! -----------------
[1015]6! OpenACC statements added
[1]7!
[668]8! Former revisions:
9! -----------------
10! $Id: prandtl_fluxes.f90 1015 2012-09-27 09:23:24Z raasch $
11!
[979]12! 978 2012-08-09 08:28:32Z fricke
13! roughness length for scalar quantities z0h added
14!
[760]15! 759 2011-09-15 13:58:31Z raasch
16! Bugfix for ts limitation
17!
[710]18! 709 2011-03-30 09:31:40Z raasch
19! formatting adjustments
20!
[668]21! 667 2010-12-23 12:06:00Z suehring/gryschka
[709]22! Changed surface boundary conditions for u and v from mirror to Dirichlet.
23! Therefore u(uzb,:,:) and v(nzb,:,:) are now representative for height z0.
[667]24! nxl-1, nxr+1, nys-1, nyn+1 replaced by nxlg, nxrg, nysg, nyng
25!
[392]26! 315 2009-05-13 10:57:59Z raasch
27! Saturation condition at (sea) surface is not used in precursor runs (only
28! in the following coupled runs)
29! Bugfix: qsws was calculated in case of constant heatflux = .FALSE.
30!
[198]31! 187 2008-08-06 16:25:09Z letzel
32! Bugfix: modification of the calculation of the vertical turbulent momentum
33! fluxes u'w' and v'w'
34! Bugfix: change definition of us_wall from 1D to 2D
35! Change: modification of the integrated version of the profile function for
36! momentum for unstable stratification (does not effect results)
37!
[110]38! 108 2007-08-24 15:10:38Z letzel
39! assume saturation at k=nzb_s_inner(j,i) for atmosphere coupled to ocean
40!
[77]41! 75 2007-03-22 09:54:05Z raasch
42! moisture renamed humidity
43!
[3]44! RCS Log replace by Id keyword, revision history cleaned up
45!
[1]46! Revision 1.19  2006/04/26 12:24:35  raasch
47! +OpenMP directives and optimization (array assignments replaced by DO loops)
48!
49! Revision 1.1  1998/01/23 10:06:06  raasch
50! Initial revision
51!
52!
53! Description:
54! ------------
55! Diagnostic computation of vertical fluxes in the Prandtl layer from the
56! values of the variables at grid point k=1
57!------------------------------------------------------------------------------!
58
59    USE arrays_3d
60    USE control_parameters
61    USE grid_variables
62    USE indices
63
64    IMPLICIT NONE
65
66    INTEGER ::  i, j, k
[1015]67    LOGICAL ::  coupled_run
[108]68    REAL    ::  a, b, e_q, rifm, uv_total, z_p
[1]69
[1015]70!
71!-- Data information for accelerators
72    !$acc data present( e, nzb_u_inner, nzb_v_inner, nzb_s_inner, pt, q, qs ) &
73    !$acc      present( qsws, rif, shf, ts, u, us, usws, v, vpt, vsws, zu, zw, z0, z0h )
[667]74!
[1]75!-- Compute theta*
76    IF ( constant_heatflux )  THEN
77!
78!--    For a given heat flux in the Prandtl layer:
79!--    for u* use the value from the previous time step
80       !$OMP PARALLEL DO
[1015]81       !$acc kernels do
[667]82       DO  i = nxlg, nxrg
83          DO  j = nysg, nyng
[1]84             ts(j,i) = -shf(j,i) / ( us(j,i) + 1E-30 )
85!
86!--          ts must be limited, because otherwise overflow may occur in case of
87!--          us=0 when computing rif further below
[759]88             IF ( ts(j,i) < -1.05E5 )  ts(j,i) = -1.0E5
89             IF ( ts(j,i) >   1.0E5 )  ts(j,i) =  1.0E5
[1]90          ENDDO
91       ENDDO
92
93    ELSE
94!
95!--    For a given surface temperature:
96!--    (the Richardson number is still the one from the previous time step)
97       !$OMP PARALLEL DO PRIVATE( a, b, k, z_p )
[1015]98       !$acc kernels do
[667]99       DO  i = nxlg, nxrg
100          DO  j = nysg, nyng
[1]101
102             k   = nzb_s_inner(j,i)
103             z_p = zu(k+1) - zw(k)
104
105             IF ( rif(j,i) >= 0.0 )  THEN
106!
107!--             Stable stratification
[978]108                ts(j,i) = kappa * ( pt(k+1,j,i) - pt(k,j,i) ) / (           &
109                                  LOG( z_p / z0h(j,i) ) +                   &
110                                  5.0 * rif(j,i) * ( z_p - z0h(j,i) ) / z_p &
[1]111                                                                )
112             ELSE
113!
114!--             Unstable stratification
115                a = SQRT( 1.0 - 16.0 * rif(j,i) )
[978]116                b = SQRT( 1.0 - 16.0 * rif(j,i) * z0h(j,i) / z_p )
[187]117
[978]118                ts(j,i) = kappa * ( pt(k+1,j,i) - pt(k,j,i) ) /  (          &
119                          LOG( z_p / z0h(j,i) ) -                           &
[187]120                          2.0 * LOG( ( 1.0 + a ) / ( 1.0 + b ) ) )
[1]121             ENDIF
122
123          ENDDO
124       ENDDO
125    ENDIF
126
127!
128!-- Compute z_p/L (corresponds to the Richardson-flux number)
[75]129    IF ( .NOT. humidity )  THEN
[1]130       !$OMP PARALLEL DO PRIVATE( k, z_p )
[1015]131       !$acc kernels do
[667]132       DO  i = nxlg, nxrg
133          DO  j = nysg, nyng
[1]134             k   = nzb_s_inner(j,i)
135             z_p = zu(k+1) - zw(k)
136             rif(j,i) = z_p * kappa * g * ts(j,i) / &
137                        ( pt(k+1,j,i) * ( us(j,i)**2 + 1E-30 ) )
138!
139!--          Limit the value range of the Richardson numbers.
140!--          This is necessary for very small velocities (u,v --> 0), because
141!--          the absolute value of rif can then become very large, which in
142!--          consequence would result in very large shear stresses and very
143!--          small momentum fluxes (both are generally unrealistic).
144             IF ( rif(j,i) < rif_min )  rif(j,i) = rif_min
145             IF ( rif(j,i) > rif_max )  rif(j,i) = rif_max
146          ENDDO
147       ENDDO
148    ELSE
149       !$OMP PARALLEL DO PRIVATE( k, z_p )
[1015]150       !$acc kernels do
[667]151       DO  i = nxlg, nxrg
152          DO  j = nysg, nyng
[1]153             k   = nzb_s_inner(j,i)
154             z_p = zu(k+1) - zw(k)
155             rif(j,i) = z_p * kappa * g *                            &
156                        ( ts(j,i) + 0.61 * pt(k+1,j,i) * qs(j,i) ) / &
157                        ( vpt(k+1,j,i) * ( us(j,i)**2 + 1E-30 ) )
158!
159!--          Limit the value range of the Richardson numbers.
160!--          This is necessary for very small velocities (u,v --> 0), because
161!--          the absolute value of rif can then become very large, which in
162!--          consequence would result in very large shear stresses and very
163!--          small momentum fluxes (both are generally unrealistic).
164             IF ( rif(j,i) < rif_min )  rif(j,i) = rif_min
165             IF ( rif(j,i) > rif_max )  rif(j,i) = rif_max
166          ENDDO
167       ENDDO       
168    ENDIF
169
170!
171!-- Compute u* at the scalars' grid points
172    !$OMP PARALLEL DO PRIVATE( a, b, k, uv_total, z_p )
[1015]173    !$acc kernels do
[1]174    DO  i = nxl, nxr
175       DO  j = nys, nyn
176
177          k   = nzb_s_inner(j,i)
178          z_p = zu(k+1) - zw(k)
179
180!
[667]181!--       Compute the absolute value of the horizontal velocity
182!--       (relative to the surface)
183          uv_total = SQRT( ( 0.5 * ( u(k+1,j,i) + u(k+1,j,i+1)        &
184                                   - u(k,j,i)   - u(k,j,i+1) ) )**2 + &
185                           ( 0.5 * ( v(k+1,j,i) + v(k+1,j+1,i)        &
186                                   - v(k,j,i)   - v(k,j+1,i) ) )**2 )   
[1]187
[667]188
[1]189          IF ( rif(j,i) >= 0.0 )  THEN
190!
191!--          Stable stratification
192             us(j,i) = kappa * uv_total / (                                &
193                                  LOG( z_p / z0(j,i) ) +                   &
194                                  5.0 * rif(j,i) * ( z_p - z0(j,i) ) / z_p &
195                                          )
196          ELSE
197!
198!--          Unstable stratification
[187]199             a = SQRT( SQRT( 1.0 - 16.0 * rif(j,i) ) )
200             b = SQRT( SQRT( 1.0 - 16.0 * rif(j,i) / z_p * z0(j,i) ) )
201
202             us(j,i) = kappa * uv_total / (                                  &
203                       LOG( z_p / z0(j,i) ) -                                &
204                       LOG( ( 1.0 + a )**2 * ( 1.0 + a**2 ) / (              &
205                            ( 1.0 + b )**2 * ( 1.0 + b**2 )   ) ) +          &
206                            2.0 * ( ATAN( a ) - ATAN( b ) )                  &
207                                           )
[1]208          ENDIF
209       ENDDO
210    ENDDO
211
212!
[187]213!-- Values of us at ghost point locations are needed for the evaluation of usws
214!-- and vsws.
[1015]215    !$acc update host( us )
[187]216    CALL exchange_horiz_2d( us )
[1015]217    !$acc update device( us )
218
[187]219!
[1]220!-- Compute u'w' for the total model domain.
221!-- First compute the corresponding component of u* and square it.
222    !$OMP PARALLEL DO PRIVATE( a, b, k, rifm, z_p )
[1015]223    !$acc kernels do
[1]224    DO  i = nxl, nxr
225       DO  j = nys, nyn
226
227          k   = nzb_u_inner(j,i)
228          z_p = zu(k+1) - zw(k)
229
230!
231!--       Compute Richardson-flux number for this point
232          rifm = 0.5 * ( rif(j,i-1) + rif(j,i) )
233          IF ( rifm >= 0.0 )  THEN
234!
235!--          Stable stratification
[667]236             usws(j,i) = kappa * ( u(k+1,j,i) - u(k,j,i) )/ (              &
[1]237                                     LOG( z_p / z0(j,i) ) +               &
238                                     5.0 * rifm * ( z_p - z0(j,i) ) / z_p &
239                                              )
240          ELSE
241!
242!--          Unstable stratification
[187]243             a = SQRT( SQRT( 1.0 - 16.0 * rifm ) )
244             b = SQRT( SQRT( 1.0 - 16.0 * rifm / z_p * z0(j,i) ) )
245
[667]246             usws(j,i) = kappa * ( u(k+1,j,i) - u(k,j,i) ) / (            &
[187]247                         LOG( z_p / z0(j,i) ) -                           &
248                         LOG( (1.0 + a )**2 * ( 1.0 + a**2 ) / (          &
249                              (1.0 + b )**2 * ( 1.0 + b**2 )   ) ) +      &
250                              2.0 * ( ATAN( a ) - ATAN( b ) )             &
[1]251                                                 )
252          ENDIF
[187]253          usws(j,i) = -usws(j,i) * 0.5 * ( us(j,i-1) + us(j,i) )
[1]254       ENDDO
255    ENDDO
256
257!
258!-- Compute v'w' for the total model domain.
259!-- First compute the corresponding component of u* and square it.
260    !$OMP PARALLEL DO PRIVATE( a, b, k, rifm, z_p )
[1015]261    !$acc kernels do
[1]262    DO  i = nxl, nxr
263       DO  j = nys, nyn
264
265          k   = nzb_v_inner(j,i)
266          z_p = zu(k+1) - zw(k)
267
268!
269!--       Compute Richardson-flux number for this point
270          rifm = 0.5 * ( rif(j-1,i) + rif(j,i) )
271          IF ( rifm >= 0.0 )  THEN
272!
273!--          Stable stratification
[667]274             vsws(j,i) = kappa * ( v(k+1,j,i) -  v(k,j,i) ) / (           &
[1]275                                     LOG( z_p / z0(j,i) ) +               &
276                                     5.0 * rifm * ( z_p - z0(j,i) ) / z_p &
277                                              )
278          ELSE
279!
280!--          Unstable stratification
[187]281             a = SQRT( SQRT( 1.0 - 16.0 * rifm ) )
282             b = SQRT( SQRT( 1.0 - 16.0 * rifm / z_p * z0(j,i) ) )
283
[667]284             vsws(j,i) = kappa * ( v(k+1,j,i) - v(k,j,i) ) / (            &
[187]285                         LOG( z_p / z0(j,i) ) -                           &
286                         LOG( (1.0 + a )**2 * ( 1.0 + a**2 ) / (          &
287                              (1.0 + b )**2 * ( 1.0 + b**2 )   ) ) +      &
288                              2.0 * ( ATAN( a ) - ATAN( b ) )             &
[1]289                                                 )
290          ENDIF
[187]291          vsws(j,i) = -vsws(j,i) * 0.5 * ( us(j-1,i) + us(j,i) )
[1]292       ENDDO
293    ENDDO
294
295!
296!-- If required compute q*
[75]297    IF ( humidity  .OR.  passive_scalar )  THEN
[1]298       IF ( constant_waterflux )  THEN
299!
300!--       For a given water flux in the Prandtl layer:
301          !$OMP PARALLEL DO
[1015]302          !$acc kernels do
[667]303          DO  i = nxlg, nxrg
304             DO  j = nysg, nyng
[1]305                qs(j,i) = -qsws(j,i) / ( us(j,i) + 1E-30 )
306             ENDDO
307          ENDDO
308         
[1015]309       ELSE
310          coupled_run = ( coupling_mode == 'atmosphere_to_ocean' .AND. run_coupled )
[1]311          !$OMP PARALLEL DO PRIVATE( a, b, k, z_p )
[1015]312          !$acc kernels do
[667]313          DO  i = nxlg, nxrg
314             DO  j = nysg, nyng
[1]315
316                k   = nzb_s_inner(j,i)
317                z_p = zu(k+1) - zw(k)
318
[108]319!
[291]320!--             Assume saturation for atmosphere coupled to ocean (but not
321!--             in case of precursor runs)
[1015]322                IF ( coupled_run )  THEN
[108]323                   e_q = 6.1 * &
324                        EXP( 0.07 * ( MIN(pt(0,j,i),pt(1,j,i)) - 273.15 ) )
325                   q(k,j,i) = 0.622 * e_q / ( surface_pressure - e_q )
326                ENDIF
[1]327                IF ( rif(j,i) >= 0.0 )  THEN
328!
329!--                Stable stratification
[978]330                   qs(j,i) = kappa * ( q(k+1,j,i) - q(k,j,i) ) / (          &
331                                  LOG( z_p / z0h(j,i) ) +                   &
332                                  5.0 * rif(j,i) * ( z_p - z0h(j,i) ) / z_p &
[1]333                                                                 )
334                ELSE
335!
336!--                Unstable stratification
[187]337                   a = SQRT( 1.0 - 16.0 * rif(j,i) ) 
[978]338                   b = SQRT( 1.0 - 16.0 * rif(j,i) * z0h(j,i) / z_p ) 
[187]339 
[978]340                   qs(j,i) = kappa * ( q(k+1,j,i) - q(k,j,i) ) /   (        &
341                             LOG( z_p / z0h(j,i) ) -                        &
[187]342                              2.0 * LOG( (1.0 + a ) / ( 1.0 + b ) ) )
[1]343                ENDIF
344
345             ENDDO
346          ENDDO
347       ENDIF
348    ENDIF
349
350!
[187]351!-- Exchange the boundaries for the momentum fluxes (only for sake of
352!-- completeness)
[1015]353    !$acc update host( usws, vsws )
[1]354    CALL exchange_horiz_2d( usws )
355    CALL exchange_horiz_2d( vsws )
[1015]356    !$acc update device( usws, vsws )
357    IF ( humidity  .OR.  passive_scalar )  THEN
358       !$acc update host( qsws )
359       CALL exchange_horiz_2d( qsws )
360       !$acc update device( qsws )
361    ENDIF
[1]362
363!
364!-- Compute the vertical kinematic heat flux
365    IF ( .NOT. constant_heatflux )  THEN
366       !$OMP PARALLEL DO
[1015]367       !$acc kernels do
[667]368       DO  i = nxlg, nxrg
369          DO  j = nysg, nyng
[1]370             shf(j,i) = -ts(j,i) * us(j,i)
371          ENDDO
372       ENDDO
373    ENDIF
374
375!
376!-- Compute the vertical water/scalar flux
[315]377    IF ( .NOT. constant_waterflux .AND. ( humidity .OR. passive_scalar ) ) THEN
[1]378       !$OMP PARALLEL DO
[1015]379       !$acc kernels do
[667]380       DO  i = nxlg, nxrg
381          DO  j = nysg, nyng
[1]382             qsws(j,i) = -qs(j,i) * us(j,i)
383          ENDDO
384       ENDDO
385    ENDIF
386
387!
388!-- Bottom boundary condition for the TKE
389    IF ( ibc_e_b == 2 )  THEN
390       !$OMP PARALLEL DO
[1015]391       !$acc kernels do
[667]392       DO  i = nxlg, nxrg
393          DO  j = nysg, nyng
[1]394             e(nzb_s_inner(j,i)+1,j,i) = ( us(j,i) / 0.1 )**2
395!
396!--          As a test: cm = 0.4
397!            e(nzb_s_inner(j,i)+1,j,i) = ( us(j,i) / 0.4 )**2
398             e(nzb_s_inner(j,i),j,i)   = e(nzb_s_inner(j,i)+1,j,i)
399          ENDDO
400       ENDDO
401    ENDIF
402
[1015]403    !$acc end data
[1]404
405 END SUBROUTINE prandtl_fluxes
Note: See TracBrowser for help on using the repository browser.