source: palm/trunk/SOURCE/lpm_advec.f90 @ 1682

Last change on this file since 1682 was 1682, checked in by knoop, 9 years ago

Code annotations made doxygen readable

  • Property svn:keywords set to Id
File size: 61.3 KB
Line 
1!> @file lpm_advec.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! Code annotations made doxygen readable
22!
23! Former revisions:
24! -----------------
25! $Id: lpm_advec.f90 1682 2015-10-07 23:56:08Z knoop $
26!
27! 1583 2015-04-15 12:16:27Z suehring
28! Bugfix: particle advection within Prandtl-layer in case of Galilei
29! transformation.
30!
31! 1369 2014-04-24 05:57:38Z raasch
32! usage of module interfaces removed
33!
34! 1359 2014-04-11 17:15:14Z hoffmann
35! New particle structure integrated.
36! Kind definition added to all floating point numbers.
37!
38! 1322 2014-03-20 16:38:49Z raasch
39! REAL constants defined as wp_kind
40!
41! 1320 2014-03-20 08:40:49Z raasch
42! ONLY-attribute added to USE-statements,
43! kind-parameters added to all INTEGER and REAL declaration statements,
44! kinds are defined in new module kinds,
45! revision history before 2012 removed,
46! comment fields (!:) to be used for variable explanations added to
47! all variable declaration statements
48!
49! 1314 2014-03-14 18:25:17Z suehring
50! Vertical logarithmic interpolation of horizontal particle speed for particles
51! between roughness height and first vertical grid level.
52!
53! 1036 2012-10-22 13:43:42Z raasch
54! code put under GPL (PALM 3.9)
55!
56! 849 2012-03-15 10:35:09Z raasch
57! initial revision (former part of advec_particles)
58!
59!
60! Description:
61! ------------
62!> Calculation of new particle positions due to advection using a simple Euler
63!> scheme. Particles may feel inertia effects. SGS transport can be included
64!> using the stochastic model of Weil et al. (2004, JAS, 61, 2877-2887).
65!------------------------------------------------------------------------------!
66 SUBROUTINE lpm_advec (ip,jp,kp)
67 
68
69    USE arrays_3d,                                                             &
70        ONLY:  de_dx, de_dy, de_dz, diss, e, u, us, usws, v, vsws, w, z0, zu,  &
71               zw
72
73    USE cpulog
74
75    USE pegrid
76
77    USE control_parameters,                                                    &
78        ONLY:  atmos_ocean_sign, cloud_droplets, dt_3d, dt_3d_reached_l, dz,   &
79               g, kappa, molecular_viscosity, prandtl_layer, topography,       &
80               u_gtrans, v_gtrans, simulated_time
81
82    USE grid_variables,                                                        &
83        ONLY:  ddx, dx, ddy, dy
84       
85    USE indices,                                                               &
86        ONLY:  nzb, nzb_s_inner, nzt
87       
88    USE kinds
89   
90    USE particle_attributes,                                                   &
91        ONLY:  block_offset, c_0, density_ratio, dt_min_part, grid_particles,  &
92               iran_part, log_z_z0, number_of_particles, number_of_sublayers,  &
93               particles, particle_groups, offset_ocean_nzt,                   &
94               offset_ocean_nzt_m1, sgs_wfu_part, sgs_wfv_part, sgs_wfw_part,  &
95               use_sgs_for_particles, vertical_particle_advection, z0_av_global
96       
97    USE statistics,                                                            &
98        ONLY:  hom
99
100    IMPLICIT NONE
101
102    INTEGER(iwp) ::  agp                         !<
103    INTEGER(iwp) ::  gp_outside_of_building(1:8) !<
104    INTEGER(iwp) ::  i                           !<
105    INTEGER(iwp) ::  ip                          !<
106    INTEGER(iwp) ::  j                           !<
107    INTEGER(iwp) ::  jp                          !<
108    INTEGER(iwp) ::  k                           !<
109    INTEGER(iwp) ::  kp                          !<
110    INTEGER(iwp) ::  kw                          !<
111    INTEGER(iwp) ::  n                           !<
112    INTEGER(iwp) ::  nb                          !<
113    INTEGER(iwp) ::  num_gp                      !<
114
115    INTEGER(iwp), DIMENSION(0:7) ::  start_index !<
116    INTEGER(iwp), DIMENSION(0:7) ::  end_index   !<
117
118    REAL(wp) ::  aa                 !<
119    REAL(wp) ::  bb                 !<
120    REAL(wp) ::  cc                 !<
121    REAL(wp) ::  d_sum              !<
122    REAL(wp) ::  d_z_p_z0           !<
123    REAL(wp) ::  dd                 !<
124    REAL(wp) ::  de_dx_int_l        !<
125    REAL(wp) ::  de_dx_int_u        !<
126    REAL(wp) ::  de_dy_int_l        !<
127    REAL(wp) ::  de_dy_int_u        !<
128    REAL(wp) ::  de_dt              !<
129    REAL(wp) ::  de_dt_min          !<
130    REAL(wp) ::  de_dz_int_l        !<
131    REAL(wp) ::  de_dz_int_u        !<
132    REAL(wp) ::  diss_int_l         !<
133    REAL(wp) ::  diss_int_u         !<
134    REAL(wp) ::  dt_gap             !<
135    REAL(wp) ::  dt_particle_m      !<
136    REAL(wp) ::  e_int_l            !<
137    REAL(wp) ::  e_int_u            !<
138    REAL(wp) ::  e_mean_int         !<
139    REAL(wp) ::  exp_arg            !<
140    REAL(wp) ::  exp_term           !<
141    REAL(wp) ::  gg                 !<
142    REAL(wp) ::  height_int         !<
143    REAL(wp) ::  height_p           !<
144    REAL(wp) ::  lagr_timescale     !<
145    REAL(wp) ::  location(1:30,1:3) !<
146    REAL(wp) ::  random_gauss       !<
147    REAL(wp) ::  u_int_l            !<
148    REAL(wp) ::  u_int_u            !<
149    REAL(wp) ::  us_int             !<
150    REAL(wp) ::  v_int_l            !<
151    REAL(wp) ::  v_int_u            !<
152    REAL(wp) ::  vv_int             !<
153    REAL(wp) ::  w_int_l            !<
154    REAL(wp) ::  w_int_u            !<
155    REAL(wp) ::  x                  !<
156    REAL(wp) ::  y                  !<
157    REAL(wp) ::  z_p                !<   
158
159    REAL(wp), DIMENSION(1:30) ::  d_gp_pl !<
160    REAL(wp), DIMENSION(1:30) ::  de_dxi  !<
161    REAL(wp), DIMENSION(1:30) ::  de_dyi  !<
162    REAL(wp), DIMENSION(1:30) ::  de_dzi  !<
163    REAL(wp), DIMENSION(1:30) ::  dissi   !<
164    REAL(wp), DIMENSION(1:30) ::  ei      !<
165
166    REAL(wp), DIMENSION(number_of_particles) ::  dens_ratio   !<
167    REAL(wp), DIMENSION(number_of_particles) ::  de_dx_int    !<
168    REAL(wp), DIMENSION(number_of_particles) ::  de_dy_int    !<
169    REAL(wp), DIMENSION(number_of_particles) ::  de_dz_int    !<
170    REAL(wp), DIMENSION(number_of_particles) ::  diss_int     !<
171    REAL(wp), DIMENSION(number_of_particles) ::  dt_particle  !<
172    REAL(wp), DIMENSION(number_of_particles) ::  e_int        !<
173    REAL(wp), DIMENSION(number_of_particles) ::  fs_int       !<
174    REAL(wp), DIMENSION(number_of_particles) ::  log_z_z0_int !<
175    REAL(wp), DIMENSION(number_of_particles) ::  u_int        !<
176    REAL(wp), DIMENSION(number_of_particles) ::  v_int        !<
177    REAL(wp), DIMENSION(number_of_particles) ::  w_int        !<
178    REAL(wp), DIMENSION(number_of_particles) ::  xv           !<
179    REAL(wp), DIMENSION(number_of_particles) ::  yv           !<
180    REAL(wp), DIMENSION(number_of_particles) ::  zv           !<
181
182    REAL(wp), DIMENSION(number_of_particles, 3) ::  rg !<
183
184    CALL cpu_log( log_point_s(44), 'lpm_advec', 'continue' )
185
186!
187!-- Determine height of Prandtl layer and distance between Prandtl-layer
188!-- height and horizontal mean roughness height, which are required for
189!-- vertical logarithmic interpolation of horizontal particle speeds
190!-- (for particles below first vertical grid level).
191    z_p      = zu(nzb+1) - zw(nzb)
192    d_z_p_z0 = 1.0_wp / ( z_p - z0_av_global )
193
194    start_index = grid_particles(kp,jp,ip)%start_index
195    end_index   = grid_particles(kp,jp,ip)%end_index
196
197    xv = particles(1:number_of_particles)%x
198    yv = particles(1:number_of_particles)%y
199    zv = particles(1:number_of_particles)%z
200
201    DO  nb = 0, 7
202
203       i = ip
204       j = jp + block_offset(nb)%j_off
205       k = kp + block_offset(nb)%k_off
206
207!
208!--    Interpolate u velocity-component
209       DO  n = start_index(nb), end_index(nb)
210!
211!--       Interpolation of the u velocity component onto particle position. 
212!--       Particles are interpolation bi-linearly in the horizontal and a
213!--       linearly in the vertical. An exception is made for particles below
214!--       the first vertical grid level in case of a prandtl layer. In this
215!--       case the horizontal particle velocity components are determined using
216!--       Monin-Obukhov relations (if branch).
217!--       First, check if particle is located below first vertical grid level
218!--       (Prandtl-layer height)
219          IF ( prandtl_layer  .AND.  particles(n)%z < z_p )  THEN
220!
221!--          Resolved-scale horizontal particle velocity is zero below z0.
222             IF ( particles(n)%z < z0_av_global )  THEN
223                u_int(n) = 0.0_wp
224             ELSE
225!
226!--             Determine the sublayer. Further used as index.
227                height_p     = ( particles(n)%z - z0_av_global )            &
228                                     * REAL( number_of_sublayers, KIND=wp ) &
229                                     * d_z_p_z0 
230!
231!--             Calculate LOG(z/z0) for exact particle height. Therefore,   
232!--             interpolate linearly between precalculated logarithm.
233                log_z_z0_int(n) = log_z_z0(INT(height_p))                      &
234                                 + ( height_p - INT(height_p) )                &
235                                 * ( log_z_z0(INT(height_p)+1)                 &
236                                      - log_z_z0(INT(height_p))                &
237                                   ) 
238!
239!--             Neutral solution is applied for all situations, e.g. also for
240!--             unstable and stable situations. Even though this is not exact
241!--             this saves a lot of CPU time since several calls of intrinsic
242!--             FORTRAN procedures (LOG, ATAN) are avoided, This is justified
243!--             as sensitivity studies revealed no significant effect of
244!--             using the neutral solution also for un/stable situations.
245!--             Calculated left and bottom index on u grid.
246                us_int = 0.5_wp * ( us(j,i) + us(j,i-1) ) 
247
248                u_int  = -usws(j,i) / ( us_int * kappa + 1E-10_wp )           & 
249                         * log_z_z0_int(n) - u_gtrans
250
251             ENDIF
252!
253!--       Particle above the first grid level. Bi-linear interpolation in the
254!--       horizontal and linear interpolation in the vertical direction.
255          ELSE
256
257             x  = xv(n) + ( 0.5_wp - i ) * dx
258             y  = yv(n) - j * dy
259             aa = x**2          + y**2
260             bb = ( dx - x )**2 + y**2
261             cc = x**2          + ( dy - y )**2
262             dd = ( dx - x )**2 + ( dy - y )**2
263             gg = aa + bb + cc + dd
264
265             u_int_l = ( ( gg - aa ) * u(k,j,i)   + ( gg - bb ) * u(k,j,i+1)   &
266                         + ( gg - cc ) * u(k,j+1,i) + ( gg - dd ) *            &
267                         u(k,j+1,i+1) ) / ( 3.0_wp * gg ) - u_gtrans
268
269             IF ( k == nzt )  THEN
270                u_int(n) = u_int_l
271             ELSE
272                u_int_u = ( ( gg-aa ) * u(k+1,j,i) + ( gg-bb ) * u(k+1,j,i+1)  &
273                            + ( gg-cc ) * u(k+1,j+1,i) + ( gg-dd ) *           &
274                            u(k+1,j+1,i+1) ) / ( 3.0_wp * gg ) - u_gtrans
275                u_int(n) = u_int_l + ( zv(n) - zu(k) ) / dz *                  &
276                           ( u_int_u - u_int_l )
277             ENDIF
278          ENDIF
279
280       ENDDO
281
282       i = ip + block_offset(nb)%i_off
283       j = jp
284       k = kp + block_offset(nb)%k_off
285!
286!--    Same procedure for interpolation of the v velocity-component
287       DO  n = start_index(nb), end_index(nb)
288          IF ( prandtl_layer  .AND.  particles(n)%z < z_p )  THEN
289
290             IF ( particles(n)%z < z0_av_global )  THEN
291!
292!--             Resolved-scale horizontal particle velocity is zero below z0.
293                v_int(n) = 0.0_wp
294             ELSE       
295!
296!--             Neutral solution is applied for all situations, e.g. also for
297!--             unstable and stable situations. Even though this is not exact
298!--             this saves a lot of CPU time since several calls of intrinsic
299!--             FORTRAN procedures (LOG, ATAN) are avoided, This is justified
300!--             as sensitivity studies revealed no significant effect of
301!--             using the neutral solution also for un/stable situations.
302!--             Calculated left and bottom index on v grid.
303                us_int = 0.5_wp * ( us(j,i) + us(j-1,i) )   
304
305                v_int  = -vsws(j,i) / ( us_int * kappa + 1E-10_wp )             &
306                         * log_z_z0_int(n) - v_gtrans
307             ENDIF
308          ELSE
309             x  = xv(n) - i * dx
310             y  = yv(n) + ( 0.5_wp - j ) * dy
311             aa = x**2          + y**2
312             bb = ( dx - x )**2 + y**2
313             cc = x**2          + ( dy - y )**2
314             dd = ( dx - x )**2 + ( dy - y )**2
315             gg = aa + bb + cc + dd
316
317             v_int_l = ( ( gg - aa ) * v(k,j,i)   + ( gg - bb ) * v(k,j,i+1)   &
318                       + ( gg - cc ) * v(k,j+1,i) + ( gg - dd ) * v(k,j+1,i+1) &
319                       ) / ( 3.0_wp * gg ) - v_gtrans
320
321             IF ( k == nzt )  THEN
322                v_int(n) = v_int_l
323             ELSE
324                v_int_u = ( ( gg-aa ) * v(k+1,j,i)   + ( gg-bb ) * v(k+1,j,i+1)   &
325                          + ( gg-cc ) * v(k+1,j+1,i) + ( gg-dd ) * v(k+1,j+1,i+1) &
326                          ) / ( 3.0_wp * gg ) - v_gtrans
327                v_int(n) = v_int_l + ( zv(n) - zu(k) ) / dz * &
328                                  ( v_int_u - v_int_l )
329             ENDIF
330          ENDIF
331
332       ENDDO
333
334       i = ip + block_offset(nb)%i_off
335       j = jp + block_offset(nb)%j_off
336       k = kp-1
337!
338!--    Same procedure for interpolation of the w velocity-component
339       DO  n = start_index(nb), end_index(nb)
340
341          IF ( vertical_particle_advection(particles(n)%group) )  THEN
342
343             x  = xv(n) - i * dx
344             y  = yv(n) - j * dy
345             aa = x**2          + y**2
346             bb = ( dx - x )**2 + y**2
347             cc = x**2          + ( dy - y )**2
348             dd = ( dx - x )**2 + ( dy - y )**2
349             gg = aa + bb + cc + dd
350
351             w_int_l = ( ( gg - aa ) * w(k,j,i)   + ( gg - bb ) * w(k,j,i+1)   &
352                       + ( gg - cc ) * w(k,j+1,i) + ( gg - dd ) * w(k,j+1,i+1) &
353                       ) / ( 3.0_wp * gg )
354
355             IF ( k == nzt )  THEN
356                w_int(n) = w_int_l
357             ELSE
358                w_int_u = ( ( gg-aa ) * w(k+1,j,i)   + &
359                            ( gg-bb ) * w(k+1,j,i+1) + &
360                            ( gg-cc ) * w(k+1,j+1,i) + &
361                            ( gg-dd ) * w(k+1,j+1,i+1) &
362                          ) / ( 3.0_wp * gg )
363                w_int(n) = w_int_l + ( zv(n) - zw(k) ) / dz * &
364                           ( w_int_u - w_int_l )
365             ENDIF
366
367          ELSE
368
369             w_int(n) = 0.0_wp
370
371          ENDIF
372
373       ENDDO
374
375    ENDDO
376
377!-- Interpolate and calculate quantities needed for calculating the SGS
378!-- velocities
379    IF ( use_sgs_for_particles )  THEN
380
381       IF ( topography == 'flat' )  THEN
382
383          DO  nb = 0,7
384
385             i = ip + block_offset(nb)%i_off
386             j = jp + block_offset(nb)%j_off
387             k = kp + block_offset(nb)%k_off
388
389             DO  n = start_index(nb), end_index(nb)
390!
391!--             Interpolate TKE
392                x  = xv(n) - i * dx
393                y  = yv(n) - j * dy
394                aa = x**2          + y**2
395                bb = ( dx - x )**2 + y**2
396                cc = x**2          + ( dy - y )**2
397                dd = ( dx - x )**2 + ( dy - y )**2
398                gg = aa + bb + cc + dd
399
400                e_int_l = ( ( gg-aa ) * e(k,j,i)   + ( gg-bb ) * e(k,j,i+1)   &
401                          + ( gg-cc ) * e(k,j+1,i) + ( gg-dd ) * e(k,j+1,i+1) &
402                          ) / ( 3.0_wp * gg )
403
404                IF ( k+1 == nzt+1 )  THEN
405                   e_int(n) = e_int_l
406                ELSE
407                   e_int_u = ( ( gg - aa ) * e(k+1,j,i)   + &
408                               ( gg - bb ) * e(k+1,j,i+1) + &
409                               ( gg - cc ) * e(k+1,j+1,i) + &
410                               ( gg - dd ) * e(k+1,j+1,i+1) &
411                            ) / ( 3.0_wp * gg )
412                   e_int(n) = e_int_l + ( zv(n) - zu(k) ) / dz * &
413                                     ( e_int_u - e_int_l )
414                ENDIF
415!
416!--             Needed to avoid NaN particle velocities
417                IF ( e_int(n) == 0.0_wp )  THEN
418                   e_int(n) = 1.0E-20_wp
419                ENDIF
420!
421!--             Interpolate the TKE gradient along x (adopt incides i,j,k and
422!--             all position variables from above (TKE))
423                de_dx_int_l = ( ( gg - aa ) * de_dx(k,j,i)   + &
424                                ( gg - bb ) * de_dx(k,j,i+1) + &
425                                ( gg - cc ) * de_dx(k,j+1,i) + &
426                                ( gg - dd ) * de_dx(k,j+1,i+1) &
427                               ) / ( 3.0_wp * gg )
428
429                IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
430                   de_dx_int(n) = de_dx_int_l
431                ELSE
432                   de_dx_int_u = ( ( gg - aa ) * de_dx(k+1,j,i)   + &
433                                   ( gg - bb ) * de_dx(k+1,j,i+1) + &
434                                   ( gg - cc ) * de_dx(k+1,j+1,i) + &
435                                   ( gg - dd ) * de_dx(k+1,j+1,i+1) &
436                                  ) / ( 3.0_wp * gg )
437                   de_dx_int(n) = de_dx_int_l + ( zv(n) - zu(k) ) / dz * &
438                                              ( de_dx_int_u - de_dx_int_l )
439                ENDIF
440!
441!--             Interpolate the TKE gradient along y
442                de_dy_int_l = ( ( gg - aa ) * de_dy(k,j,i)   + &
443                                ( gg - bb ) * de_dy(k,j,i+1) + &
444                                ( gg - cc ) * de_dy(k,j+1,i) + &
445                                ( gg - dd ) * de_dy(k,j+1,i+1) &
446                               ) / ( 3.0_wp * gg )
447                IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
448                   de_dy_int(n) = de_dy_int_l
449                ELSE
450                   de_dy_int_u = ( ( gg - aa ) * de_dy(k+1,j,i)   + &
451                                  ( gg - bb ) * de_dy(k+1,j,i+1) + &
452                                  ( gg - cc ) * de_dy(k+1,j+1,i) + &
453                                  ( gg - dd ) * de_dy(k+1,j+1,i+1) &
454                                  ) / ( 3.0_wp * gg )
455                   de_dy_int(n) = de_dy_int_l + ( zv(n) - zu(k) ) / dz * &
456                                              ( de_dy_int_u - de_dy_int_l )
457                ENDIF
458
459!
460!--             Interpolate the TKE gradient along z
461                IF ( zv(n) < 0.5_wp * dz )  THEN
462                   de_dz_int(n) = 0.0_wp
463                ELSE
464                   de_dz_int_l = ( ( gg - aa ) * de_dz(k,j,i)   + &
465                                   ( gg - bb ) * de_dz(k,j,i+1) + &
466                                   ( gg - cc ) * de_dz(k,j+1,i) + &
467                                   ( gg - dd ) * de_dz(k,j+1,i+1) &
468                                  ) / ( 3.0_wp * gg )
469
470                   IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
471                      de_dz_int(n) = de_dz_int_l
472                   ELSE
473                      de_dz_int_u = ( ( gg - aa ) * de_dz(k+1,j,i)   + &
474                                      ( gg - bb ) * de_dz(k+1,j,i+1) + &
475                                      ( gg - cc ) * de_dz(k+1,j+1,i) + &
476                                      ( gg - dd ) * de_dz(k+1,j+1,i+1) &
477                                     ) / ( 3.0_wp * gg )
478                      de_dz_int(n) = de_dz_int_l + ( zv(n) - zu(k) ) / dz * &
479                                                 ( de_dz_int_u - de_dz_int_l )
480                   ENDIF
481                ENDIF
482
483!
484!--             Interpolate the dissipation of TKE
485                diss_int_l = ( ( gg - aa ) * diss(k,j,i)   + &
486                               ( gg - bb ) * diss(k,j,i+1) + &
487                               ( gg - cc ) * diss(k,j+1,i) + &
488                               ( gg - dd ) * diss(k,j+1,i+1) &
489                              ) / ( 3.0_wp * gg )
490
491                IF ( k == nzt )  THEN
492                   diss_int(n) = diss_int_l
493                ELSE
494                   diss_int_u = ( ( gg - aa ) * diss(k+1,j,i)   + &
495                                  ( gg - bb ) * diss(k+1,j,i+1) + &
496                                  ( gg - cc ) * diss(k+1,j+1,i) + &
497                                  ( gg - dd ) * diss(k+1,j+1,i+1) &
498                                 ) / ( 3.0_wp * gg )
499                   diss_int(n) = diss_int_l + ( zv(n) - zu(k) ) / dz * &
500                                           ( diss_int_u - diss_int_l )
501                ENDIF
502
503             ENDDO
504          ENDDO
505
506       ELSE ! non-flat topography, e.g., buildings
507
508          DO  n = 1, number_of_particles
509
510             i = particles(n)%x * ddx
511             j = particles(n)%y * ddy
512             k = ( zv(n) + 0.5_wp * dz * atmos_ocean_sign ) / dz  &
513                 + offset_ocean_nzt                      ! only exact if eq.dist
514!
515!--          In case that there are buildings it has to be determined
516!--          how many of the gridpoints defining the particle box are
517!--          situated within a building
518!--          gp_outside_of_building(1): i,j,k
519!--          gp_outside_of_building(2): i,j+1,k
520!--          gp_outside_of_building(3): i,j,k+1
521!--          gp_outside_of_building(4): i,j+1,k+1
522!--          gp_outside_of_building(5): i+1,j,k
523!--          gp_outside_of_building(6): i+1,j+1,k
524!--          gp_outside_of_building(7): i+1,j,k+1
525!--          gp_outside_of_building(8): i+1,j+1,k+1
526
527             gp_outside_of_building = 0
528             location = 0.0_wp
529             num_gp = 0
530
531             IF ( k > nzb_s_inner(j,i)  .OR.  nzb_s_inner(j,i) == 0 )  THEN
532                num_gp = num_gp + 1
533                gp_outside_of_building(1) = 1
534                location(num_gp,1) = i * dx
535                location(num_gp,2) = j * dy
536                location(num_gp,3) = k * dz - 0.5_wp * dz
537                ei(num_gp)     = e(k,j,i)
538                dissi(num_gp)  = diss(k,j,i)
539                de_dxi(num_gp) = de_dx(k,j,i)
540                de_dyi(num_gp) = de_dy(k,j,i)
541                de_dzi(num_gp) = de_dz(k,j,i)
542             ENDIF
543
544             IF ( k > nzb_s_inner(j+1,i)  .OR.  nzb_s_inner(j+1,i) == 0 ) &
545             THEN
546                num_gp = num_gp + 1
547                gp_outside_of_building(2) = 1
548                location(num_gp,1) = i * dx
549                location(num_gp,2) = (j+1) * dy
550                location(num_gp,3) = k * dz - 0.5_wp * dz
551                ei(num_gp)     = e(k,j+1,i)
552                dissi(num_gp)  = diss(k,j+1,i)
553                de_dxi(num_gp) = de_dx(k,j+1,i)
554                de_dyi(num_gp) = de_dy(k,j+1,i)
555                de_dzi(num_gp) = de_dz(k,j+1,i)
556             ENDIF
557
558             IF ( k+1 > nzb_s_inner(j,i)  .OR.  nzb_s_inner(j,i) == 0 )  THEN
559                num_gp = num_gp + 1
560                gp_outside_of_building(3) = 1
561                location(num_gp,1) = i * dx
562                location(num_gp,2) = j * dy
563                location(num_gp,3) = (k+1) * dz - 0.5_wp * dz
564                ei(num_gp)     = e(k+1,j,i)
565                dissi(num_gp)  = diss(k+1,j,i)
566                de_dxi(num_gp) = de_dx(k+1,j,i)
567                de_dyi(num_gp) = de_dy(k+1,j,i)
568                de_dzi(num_gp) = de_dz(k+1,j,i)
569             ENDIF
570
571             IF ( k+1 > nzb_s_inner(j+1,i)  .OR.  nzb_s_inner(j+1,i) == 0 ) &
572             THEN
573                num_gp = num_gp + 1
574                gp_outside_of_building(4) = 1
575                location(num_gp,1) = i * dx
576                location(num_gp,2) = (j+1) * dy
577                location(num_gp,3) = (k+1) * dz - 0.5_wp * dz
578                ei(num_gp)     = e(k+1,j+1,i)
579                dissi(num_gp)  = diss(k+1,j+1,i)
580                de_dxi(num_gp) = de_dx(k+1,j+1,i)
581                de_dyi(num_gp) = de_dy(k+1,j+1,i)
582                de_dzi(num_gp) = de_dz(k+1,j+1,i)
583             ENDIF
584
585             IF ( k > nzb_s_inner(j,i+1)  .OR.  nzb_s_inner(j,i+1) == 0 ) &
586             THEN
587                num_gp = num_gp + 1
588                gp_outside_of_building(5) = 1
589                location(num_gp,1) = (i+1) * dx
590                location(num_gp,2) = j * dy
591                location(num_gp,3) = k * dz - 0.5_wp * dz
592                ei(num_gp)     = e(k,j,i+1)
593                dissi(num_gp)  = diss(k,j,i+1)
594                de_dxi(num_gp) = de_dx(k,j,i+1)
595                de_dyi(num_gp) = de_dy(k,j,i+1)
596                de_dzi(num_gp) = de_dz(k,j,i+1)
597             ENDIF
598
599             IF ( k > nzb_s_inner(j+1,i+1)  .OR.  nzb_s_inner(j+1,i+1) == 0 ) &
600             THEN
601                num_gp = num_gp + 1
602                gp_outside_of_building(6) = 1
603                location(num_gp,1) = (i+1) * dx
604                location(num_gp,2) = (j+1) * dy
605                location(num_gp,3) = k * dz - 0.5_wp * dz
606                ei(num_gp)     = e(k,j+1,i+1)
607                dissi(num_gp)  = diss(k,j+1,i+1)
608                de_dxi(num_gp) = de_dx(k,j+1,i+1)
609                de_dyi(num_gp) = de_dy(k,j+1,i+1)
610                de_dzi(num_gp) = de_dz(k,j+1,i+1)
611             ENDIF
612
613             IF ( k+1 > nzb_s_inner(j,i+1)  .OR.  nzb_s_inner(j,i+1) == 0 ) &
614             THEN
615                num_gp = num_gp + 1
616                gp_outside_of_building(7) = 1
617                location(num_gp,1) = (i+1) * dx
618                location(num_gp,2) = j * dy
619                location(num_gp,3) = (k+1) * dz - 0.5_wp * dz
620                ei(num_gp)     = e(k+1,j,i+1)
621                dissi(num_gp)  = diss(k+1,j,i+1)
622                de_dxi(num_gp) = de_dx(k+1,j,i+1)
623                de_dyi(num_gp) = de_dy(k+1,j,i+1)
624                de_dzi(num_gp) = de_dz(k+1,j,i+1)
625             ENDIF
626
627             IF ( k+1 > nzb_s_inner(j+1,i+1)  .OR.  nzb_s_inner(j+1,i+1) == 0)&
628             THEN
629                num_gp = num_gp + 1
630                gp_outside_of_building(8) = 1
631                location(num_gp,1) = (i+1) * dx
632                location(num_gp,2) = (j+1) * dy
633                location(num_gp,3) = (k+1) * dz - 0.5_wp * dz
634                ei(num_gp)     = e(k+1,j+1,i+1)
635                dissi(num_gp)  = diss(k+1,j+1,i+1)
636                de_dxi(num_gp) = de_dx(k+1,j+1,i+1)
637                de_dyi(num_gp) = de_dy(k+1,j+1,i+1)
638                de_dzi(num_gp) = de_dz(k+1,j+1,i+1)
639             ENDIF
640
641!
642!--          If all gridpoints are situated outside of a building, then the
643!--          ordinary interpolation scheme can be used.
644             IF ( num_gp == 8 )  THEN
645
646                x  = particles(n)%x - i * dx
647                y  = particles(n)%y - j * dy
648                aa = x**2          + y**2
649                bb = ( dx - x )**2 + y**2
650                cc = x**2          + ( dy - y )**2
651                dd = ( dx - x )**2 + ( dy - y )**2
652                gg = aa + bb + cc + dd
653
654                e_int_l = ( ( gg - aa ) * e(k,j,i)   + ( gg - bb ) * e(k,j,i+1)   &
655                          + ( gg - cc ) * e(k,j+1,i) + ( gg - dd ) * e(k,j+1,i+1) &
656                          ) / ( 3.0_wp * gg )
657
658                IF ( k == nzt )  THEN
659                   e_int(n) = e_int_l
660                ELSE
661                   e_int_u = ( ( gg - aa ) * e(k+1,j,i)   + &
662                               ( gg - bb ) * e(k+1,j,i+1) + &
663                               ( gg - cc ) * e(k+1,j+1,i) + &
664                               ( gg - dd ) * e(k+1,j+1,i+1) &
665                             ) / ( 3.0_wp * gg )
666                   e_int(n) = e_int_l + ( zv(n) - zu(k) ) / dz * &
667                                     ( e_int_u - e_int_l )
668                ENDIF
669!
670!--             Needed to avoid NaN particle velocities
671                IF ( e_int(n) == 0.0_wp )  THEN
672                   e_int(n) = 1.0E-20_wp
673                ENDIF
674!
675!--             Interpolate the TKE gradient along x (adopt incides i,j,k
676!--             and all position variables from above (TKE))
677                de_dx_int_l = ( ( gg - aa ) * de_dx(k,j,i)   + &
678                                ( gg - bb ) * de_dx(k,j,i+1) + &
679                                ( gg - cc ) * de_dx(k,j+1,i) + &
680                                ( gg - dd ) * de_dx(k,j+1,i+1) &
681                              ) / ( 3.0_wp * gg )
682
683                IF ( ( k == nzt )  .OR.  ( k == nzb ) )  THEN
684                   de_dx_int(n) = de_dx_int_l
685                ELSE
686                   de_dx_int_u = ( ( gg - aa ) * de_dx(k+1,j,i)   + &
687                                   ( gg - bb ) * de_dx(k+1,j,i+1) + &
688                                   ( gg - cc ) * de_dx(k+1,j+1,i) + &
689                                   ( gg - dd ) * de_dx(k+1,j+1,i+1) &
690                                 ) / ( 3.0_wp * gg )
691                   de_dx_int(n) = de_dx_int_l + ( zv(n) - zu(k) ) / &
692                                           dz * ( de_dx_int_u - de_dx_int_l )
693                ENDIF
694
695!
696!--             Interpolate the TKE gradient along y
697                de_dy_int_l = ( ( gg - aa ) * de_dy(k,j,i)   + &
698                                ( gg - bb ) * de_dy(k,j,i+1) + &
699                                ( gg - cc ) * de_dy(k,j+1,i) + &
700                                ( gg - dd ) * de_dy(k,j+1,i+1) &
701                              ) / ( 3.0_wp * gg )
702                IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
703                   de_dy_int(n) = de_dy_int_l
704                ELSE
705                   de_dy_int_u = ( ( gg - aa ) * de_dy(k+1,j,i)   + &
706                                   ( gg - bb ) * de_dy(k+1,j,i+1) + &
707                                   ( gg - cc ) * de_dy(k+1,j+1,i) + &
708                                   ( gg - dd ) * de_dy(k+1,j+1,i+1) &
709                                 ) / ( 3.0_wp * gg )
710                   de_dy_int(n) = de_dy_int_l + ( zv(n) - zu(k) ) / &
711                                           dz * ( de_dy_int_u - de_dy_int_l )
712                ENDIF
713
714!
715!--             Interpolate the TKE gradient along z
716                IF ( zv(n) < 0.5_wp * dz )  THEN
717                   de_dz_int(n) = 0.0_wp
718                ELSE
719                   de_dz_int_l = ( ( gg - aa ) * de_dz(k,j,i)   + &
720                                   ( gg - bb ) * de_dz(k,j,i+1) + &
721                                   ( gg - cc ) * de_dz(k,j+1,i) + &
722                                   ( gg - dd ) * de_dz(k,j+1,i+1) &
723                                 ) / ( 3.0_wp * gg )
724
725                   IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
726                      de_dz_int(n) = de_dz_int_l
727                   ELSE
728                      de_dz_int_u = ( ( gg - aa ) * de_dz(k+1,j,i)   + &
729                                      ( gg - bb ) * de_dz(k+1,j,i+1) + &
730                                      ( gg - cc ) * de_dz(k+1,j+1,i) + &
731                                      ( gg - dd ) * de_dz(k+1,j+1,i+1) &
732                                    ) / ( 3.0_wp * gg )
733                      de_dz_int(n) = de_dz_int_l + ( zv(n) - zu(k) ) /&
734                                           dz * ( de_dz_int_u - de_dz_int_l )
735                   ENDIF
736                ENDIF
737
738!
739!--             Interpolate the dissipation of TKE
740                diss_int_l = ( ( gg - aa ) * diss(k,j,i)   + &
741                               ( gg - bb ) * diss(k,j,i+1) + &
742                               ( gg - cc ) * diss(k,j+1,i) + &
743                               ( gg - dd ) * diss(k,j+1,i+1) &
744                             ) / ( 3.0_wp * gg )
745
746                IF ( k == nzt )  THEN
747                   diss_int(n) = diss_int_l
748                ELSE
749                   diss_int_u = ( ( gg - aa ) * diss(k+1,j,i)   + &
750                                  ( gg - bb ) * diss(k+1,j,i+1) + &
751                                  ( gg - cc ) * diss(k+1,j+1,i) + &
752                                  ( gg - dd ) * diss(k+1,j+1,i+1) &
753                                ) / ( 3.0_wp * gg )
754                   diss_int(n) = diss_int_l + ( zv(n) - zu(k) ) / dz *&
755                                           ( diss_int_u - diss_int_l )
756                ENDIF
757
758             ELSE
759
760!
761!--             If wall between gridpoint 1 and gridpoint 5, then
762!--             Neumann boundary condition has to be applied
763                IF ( gp_outside_of_building(1) == 1  .AND. &
764                     gp_outside_of_building(5) == 0 )  THEN
765                   num_gp = num_gp + 1
766                   location(num_gp,1) = i * dx + 0.5_wp * dx
767                   location(num_gp,2) = j * dy
768                   location(num_gp,3) = k * dz - 0.5_wp * dz
769                   ei(num_gp)     = e(k,j,i)
770                   dissi(num_gp)  = diss(k,j,i)
771                   de_dxi(num_gp) = 0.0_wp
772                   de_dyi(num_gp) = de_dy(k,j,i)
773                   de_dzi(num_gp) = de_dz(k,j,i)
774                ENDIF
775
776                IF ( gp_outside_of_building(5) == 1  .AND. &
777                   gp_outside_of_building(1) == 0 )  THEN
778                   num_gp = num_gp + 1
779                   location(num_gp,1) = i * dx + 0.5_wp * dx
780                   location(num_gp,2) = j * dy
781                   location(num_gp,3) = k * dz - 0.5_wp * dz
782                   ei(num_gp)     = e(k,j,i+1)
783                   dissi(num_gp)  = diss(k,j,i+1)
784                   de_dxi(num_gp) = 0.0_wp
785                   de_dyi(num_gp) = de_dy(k,j,i+1)
786                   de_dzi(num_gp) = de_dz(k,j,i+1)
787                ENDIF
788
789!
790!--             If wall between gridpoint 5 and gridpoint 6, then
791!--             then Neumann boundary condition has to be applied
792                IF ( gp_outside_of_building(5) == 1  .AND. &
793                     gp_outside_of_building(6) == 0 )  THEN
794                   num_gp = num_gp + 1
795                   location(num_gp,1) = (i+1) * dx
796                   location(num_gp,2) = j * dy + 0.5_wp * dy
797                   location(num_gp,3) = k * dz - 0.5_wp * dz
798                   ei(num_gp)     = e(k,j,i+1)
799                   dissi(num_gp)  = diss(k,j,i+1)
800                   de_dxi(num_gp) = de_dx(k,j,i+1)
801                   de_dyi(num_gp) = 0.0_wp
802                   de_dzi(num_gp) = de_dz(k,j,i+1)
803                ENDIF
804
805                IF ( gp_outside_of_building(6) == 1  .AND. &
806                     gp_outside_of_building(5) == 0 )  THEN
807                   num_gp = num_gp + 1
808                   location(num_gp,1) = (i+1) * dx
809                   location(num_gp,2) = j * dy + 0.5_wp * dy
810                   location(num_gp,3) = k * dz - 0.5_wp * dz
811                   ei(num_gp)     = e(k,j+1,i+1)
812                   dissi(num_gp)  = diss(k,j+1,i+1)
813                   de_dxi(num_gp) = de_dx(k,j+1,i+1)
814                   de_dyi(num_gp) = 0.0_wp
815                   de_dzi(num_gp) = de_dz(k,j+1,i+1)
816                ENDIF
817
818!
819!--             If wall between gridpoint 2 and gridpoint 6, then
820!--             Neumann boundary condition has to be applied
821                IF ( gp_outside_of_building(2) == 1  .AND. &
822                     gp_outside_of_building(6) == 0 )  THEN
823                   num_gp = num_gp + 1
824                   location(num_gp,1) = i * dx + 0.5_wp * dx
825                   location(num_gp,2) = (j+1) * dy
826                   location(num_gp,3) = k * dz - 0.5_wp * dz
827                   ei(num_gp)     = e(k,j+1,i)
828                   dissi(num_gp)  = diss(k,j+1,i)
829                   de_dxi(num_gp) = 0.0_wp
830                   de_dyi(num_gp) = de_dy(k,j+1,i)
831                   de_dzi(num_gp) = de_dz(k,j+1,i)
832                ENDIF
833
834                IF ( gp_outside_of_building(6) == 1  .AND. &
835                     gp_outside_of_building(2) == 0 )  THEN
836                   num_gp = num_gp + 1
837                   location(num_gp,1) = i * dx + 0.5_wp * dx
838                   location(num_gp,2) = (j+1) * dy
839                   location(num_gp,3) = k * dz - 0.5_wp * dz
840                   ei(num_gp)     = e(k,j+1,i+1)
841                   dissi(num_gp)  = diss(k,j+1,i+1)
842                   de_dxi(num_gp) = 0.0_wp
843                   de_dyi(num_gp) = de_dy(k,j+1,i+1)
844                   de_dzi(num_gp) = de_dz(k,j+1,i+1)
845                ENDIF
846
847!
848!--             If wall between gridpoint 1 and gridpoint 2, then
849!--             Neumann boundary condition has to be applied
850                IF ( gp_outside_of_building(1) == 1  .AND. &
851                     gp_outside_of_building(2) == 0 )  THEN
852                   num_gp = num_gp + 1
853                   location(num_gp,1) = i * dx
854                   location(num_gp,2) = j * dy + 0.5_wp * dy
855                   location(num_gp,3) = k * dz - 0.5_wp * dz
856                   ei(num_gp)     = e(k,j,i)
857                   dissi(num_gp)  = diss(k,j,i)
858                   de_dxi(num_gp) = de_dx(k,j,i)
859                   de_dyi(num_gp) = 0.0_wp
860                   de_dzi(num_gp) = de_dz(k,j,i)
861                ENDIF
862
863                IF ( gp_outside_of_building(2) == 1  .AND. &
864                     gp_outside_of_building(1) == 0 )  THEN
865                   num_gp = num_gp + 1
866                   location(num_gp,1) = i * dx
867                   location(num_gp,2) = j * dy + 0.5_wp * dy
868                   location(num_gp,3) = k * dz - 0.5_wp * dz
869                   ei(num_gp)     = e(k,j+1,i)
870                   dissi(num_gp)  = diss(k,j+1,i)
871                   de_dxi(num_gp) = de_dx(k,j+1,i)
872                   de_dyi(num_gp) = 0.0_wp
873                   de_dzi(num_gp) = de_dz(k,j+1,i)
874                ENDIF
875
876!
877!--             If wall between gridpoint 3 and gridpoint 7, then
878!--             Neumann boundary condition has to be applied
879                IF ( gp_outside_of_building(3) == 1  .AND. &
880                     gp_outside_of_building(7) == 0 )  THEN
881                   num_gp = num_gp + 1
882                   location(num_gp,1) = i * dx + 0.5_wp * dx
883                   location(num_gp,2) = j * dy
884                   location(num_gp,3) = k * dz + 0.5_wp * dz
885                   ei(num_gp)     = e(k+1,j,i)
886                   dissi(num_gp)  = diss(k+1,j,i)
887                   de_dxi(num_gp) = 0.0_wp
888                   de_dyi(num_gp) = de_dy(k+1,j,i)
889                   de_dzi(num_gp) = de_dz(k+1,j,i) 
890                ENDIF
891
892                IF ( gp_outside_of_building(7) == 1  .AND. &
893                     gp_outside_of_building(3) == 0 )  THEN
894                   num_gp = num_gp + 1
895                   location(num_gp,1) = i * dx + 0.5_wp * dx
896                   location(num_gp,2) = j * dy
897                   location(num_gp,3) = k * dz + 0.5_wp * dz
898                   ei(num_gp)     = e(k+1,j,i+1)
899                   dissi(num_gp)  = diss(k+1,j,i+1)
900                   de_dxi(num_gp) = 0.0_wp
901                   de_dyi(num_gp) = de_dy(k+1,j,i+1)
902                   de_dzi(num_gp) = de_dz(k+1,j,i+1)
903                ENDIF
904
905!
906!--             If wall between gridpoint 7 and gridpoint 8, then
907!--             Neumann boundary condition has to be applied
908                IF ( gp_outside_of_building(7) == 1  .AND. &
909                     gp_outside_of_building(8) == 0 )  THEN
910                   num_gp = num_gp + 1
911                   location(num_gp,1) = (i+1) * dx
912                   location(num_gp,2) = j * dy + 0.5_wp * dy
913                   location(num_gp,3) = k * dz + 0.5_wp * dz
914                   ei(num_gp)     = e(k+1,j,i+1)
915                   dissi(num_gp)  = diss(k+1,j,i+1)
916                   de_dxi(num_gp) = de_dx(k+1,j,i+1)
917                   de_dyi(num_gp) = 0.0_wp
918                   de_dzi(num_gp) = de_dz(k+1,j,i+1)
919                ENDIF
920
921                IF ( gp_outside_of_building(8) == 1  .AND. &
922                     gp_outside_of_building(7) == 0 )  THEN
923                   num_gp = num_gp + 1
924                   location(num_gp,1) = (i+1) * dx
925                   location(num_gp,2) = j * dy + 0.5_wp * dy
926                   location(num_gp,3) = k * dz + 0.5_wp * dz
927                   ei(num_gp)     = e(k+1,j+1,i+1)
928                   dissi(num_gp)  = diss(k+1,j+1,i+1)
929                   de_dxi(num_gp) = de_dx(k+1,j+1,i+1)
930                   de_dyi(num_gp) = 0.0_wp
931                   de_dzi(num_gp) = de_dz(k+1,j+1,i+1)
932                ENDIF
933
934!
935!--             If wall between gridpoint 4 and gridpoint 8, then
936!--             Neumann boundary condition has to be applied
937                IF ( gp_outside_of_building(4) == 1  .AND. &
938                     gp_outside_of_building(8) == 0 )  THEN
939                   num_gp = num_gp + 1
940                   location(num_gp,1) = i * dx + 0.5_wp * dx
941                   location(num_gp,2) = (j+1) * dy
942                   location(num_gp,3) = k * dz + 0.5_wp * dz
943                   ei(num_gp)     = e(k+1,j+1,i)
944                   dissi(num_gp)  = diss(k+1,j+1,i)
945                   de_dxi(num_gp) = 0.0_wp
946                   de_dyi(num_gp) = de_dy(k+1,j+1,i)
947                   de_dzi(num_gp) = de_dz(k+1,j+1,i)
948                ENDIF
949
950                IF ( gp_outside_of_building(8) == 1  .AND. &
951                     gp_outside_of_building(4) == 0 )  THEN
952                   num_gp = num_gp + 1
953                   location(num_gp,1) = i * dx + 0.5_wp * dx
954                   location(num_gp,2) = (j+1) * dy
955                   location(num_gp,3) = k * dz + 0.5_wp * dz
956                   ei(num_gp)     = e(k+1,j+1,i+1)
957                   dissi(num_gp)  = diss(k+1,j+1,i+1)
958                   de_dxi(num_gp) = 0.0_wp
959                   de_dyi(num_gp) = de_dy(k+1,j+1,i+1)
960                   de_dzi(num_gp) = de_dz(k+1,j+1,i+1)
961                ENDIF
962
963!
964!--             If wall between gridpoint 3 and gridpoint 4, then
965!--             Neumann boundary condition has to be applied
966                IF ( gp_outside_of_building(3) == 1  .AND. &
967                     gp_outside_of_building(4) == 0 )  THEN
968                   num_gp = num_gp + 1
969                   location(num_gp,1) = i * dx
970                   location(num_gp,2) = j * dy + 0.5_wp * dy
971                   location(num_gp,3) = k * dz + 0.5_wp * dz
972                   ei(num_gp)     = e(k+1,j,i)
973                   dissi(num_gp)  = diss(k+1,j,i)
974                   de_dxi(num_gp) = de_dx(k+1,j,i)
975                   de_dyi(num_gp) = 0.0_wp
976                   de_dzi(num_gp) = de_dz(k+1,j,i)
977                ENDIF
978
979                IF ( gp_outside_of_building(4) == 1  .AND. &
980                     gp_outside_of_building(3) == 0 )  THEN
981                   num_gp = num_gp + 1
982                   location(num_gp,1) = i * dx
983                   location(num_gp,2) = j * dy + 0.5_wp * dy
984                   location(num_gp,3) = k * dz + 0.5_wp * dz
985                   ei(num_gp)     = e(k+1,j+1,i)
986                   dissi(num_gp)  = diss(k+1,j+1,i)
987                   de_dxi(num_gp) = de_dx(k+1,j+1,i)
988                   de_dyi(num_gp) = 0.0_wp
989                   de_dzi(num_gp) = de_dz(k+1,j+1,i)
990                ENDIF
991
992!
993!--             If wall between gridpoint 1 and gridpoint 3, then
994!--             Neumann boundary condition has to be applied
995!--             (only one case as only building beneath is possible)
996                IF ( gp_outside_of_building(1) == 0  .AND. &
997                     gp_outside_of_building(3) == 1 )  THEN
998                   num_gp = num_gp + 1
999                   location(num_gp,1) = i * dx
1000                   location(num_gp,2) = j * dy
1001                   location(num_gp,3) = k * dz
1002                   ei(num_gp)     = e(k+1,j,i)
1003                   dissi(num_gp)  = diss(k+1,j,i)
1004                   de_dxi(num_gp) = de_dx(k+1,j,i)
1005                   de_dyi(num_gp) = de_dy(k+1,j,i)
1006                   de_dzi(num_gp) = 0.0_wp
1007                ENDIF
1008
1009!
1010!--             If wall between gridpoint 5 and gridpoint 7, then
1011!--             Neumann boundary condition has to be applied
1012!--             (only one case as only building beneath is possible)
1013                IF ( gp_outside_of_building(5) == 0  .AND. &
1014                     gp_outside_of_building(7) == 1 )  THEN
1015                   num_gp = num_gp + 1
1016                   location(num_gp,1) = (i+1) * dx
1017                   location(num_gp,2) = j * dy
1018                   location(num_gp,3) = k * dz
1019                   ei(num_gp)     = e(k+1,j,i+1)
1020                   dissi(num_gp)  = diss(k+1,j,i+1)
1021                   de_dxi(num_gp) = de_dx(k+1,j,i+1)
1022                   de_dyi(num_gp) = de_dy(k+1,j,i+1)
1023                   de_dzi(num_gp) = 0.0_wp
1024                ENDIF
1025
1026!
1027!--             If wall between gridpoint 2 and gridpoint 4, then
1028!--             Neumann boundary condition has to be applied
1029!--             (only one case as only building beneath is possible)
1030                IF ( gp_outside_of_building(2) == 0  .AND. &
1031                     gp_outside_of_building(4) == 1 )  THEN
1032                   num_gp = num_gp + 1
1033                   location(num_gp,1) = i * dx
1034                   location(num_gp,2) = (j+1) * dy
1035                   location(num_gp,3) = k * dz
1036                   ei(num_gp)     = e(k+1,j+1,i)
1037                   dissi(num_gp)  = diss(k+1,j+1,i)
1038                   de_dxi(num_gp) = de_dx(k+1,j+1,i)
1039                   de_dyi(num_gp) = de_dy(k+1,j+1,i)
1040                   de_dzi(num_gp) = 0.0_wp
1041                ENDIF
1042
1043!
1044!--             If wall between gridpoint 6 and gridpoint 8, then
1045!--             Neumann boundary condition has to be applied
1046!--             (only one case as only building beneath is possible)
1047                IF ( gp_outside_of_building(6) == 0  .AND. &
1048                     gp_outside_of_building(8) == 1 )  THEN
1049                   num_gp = num_gp + 1
1050                   location(num_gp,1) = (i+1) * dx
1051                   location(num_gp,2) = (j+1) * dy
1052                   location(num_gp,3) = k * dz
1053                   ei(num_gp)     = e(k+1,j+1,i+1)
1054                   dissi(num_gp)  = diss(k+1,j+1,i+1)
1055                   de_dxi(num_gp) = de_dx(k+1,j+1,i+1)
1056                   de_dyi(num_gp) = de_dy(k+1,j+1,i+1)
1057                   de_dzi(num_gp) = 0.0_wp
1058                ENDIF
1059
1060!
1061!--             Carry out the interpolation
1062                IF ( num_gp == 1 )  THEN
1063!
1064!--                If only one of the gridpoints is situated outside of the
1065!--                building, it follows that the values at the particle
1066!--                location are the same as the gridpoint values
1067                   e_int(n)     = ei(num_gp)
1068                   diss_int(n)  = dissi(num_gp)
1069                   de_dx_int(n) = de_dxi(num_gp)
1070                   de_dy_int(n) = de_dyi(num_gp)
1071                   de_dz_int(n) = de_dzi(num_gp)
1072                ELSE IF ( num_gp > 1 )  THEN
1073
1074                   d_sum = 0.0_wp
1075!
1076!--                Evaluation of the distances between the gridpoints
1077!--                contributing to the interpolated values, and the particle
1078!--                location
1079                   DO  agp = 1, num_gp
1080                      d_gp_pl(agp) = ( particles(n)%x-location(agp,1) )**2  &
1081                                   + ( particles(n)%y-location(agp,2) )**2  &
1082                                   + ( zv(n)-location(agp,3) )**2
1083                      d_sum        = d_sum + d_gp_pl(agp)
1084                   ENDDO
1085
1086!
1087!--                Finally the interpolation can be carried out
1088                   e_int(n)     = 0.0_wp 
1089                   diss_int(n)  = 0.0_wp 
1090                   de_dx_int(n) = 0.0_wp 
1091                   de_dy_int(n) = 0.0_wp 
1092                   de_dz_int(n) = 0.0_wp 
1093                   DO  agp = 1, num_gp
1094                      e_int(n)     = e_int(n)     + ( d_sum - d_gp_pl(agp) ) * &
1095                                             ei(agp) / ( (num_gp-1) * d_sum )
1096                      diss_int(n)  = diss_int(n)  + ( d_sum - d_gp_pl(agp) ) * &
1097                                          dissi(agp) / ( (num_gp-1) * d_sum )
1098                      de_dx_int(n) = de_dx_int(n) + ( d_sum - d_gp_pl(agp) ) * &
1099                                         de_dxi(agp) / ( (num_gp-1) * d_sum )
1100                      de_dy_int(n) = de_dy_int(n) + ( d_sum - d_gp_pl(agp) ) * &
1101                                         de_dyi(agp) / ( (num_gp-1) * d_sum )
1102                      de_dz_int(n) = de_dz_int(n) + ( d_sum - d_gp_pl(agp) ) * &
1103                                         de_dzi(agp) / ( (num_gp-1) * d_sum )
1104                   ENDDO
1105
1106                ENDIF
1107
1108             ENDIF
1109          ENDDO
1110       ENDIF
1111
1112       DO nb = 0,7
1113          i = ip + block_offset(nb)%i_off
1114          j = jp + block_offset(nb)%j_off
1115          k = kp + block_offset(nb)%k_off
1116
1117          DO  n = start_index(nb), end_index(nb)
1118!
1119!--          Vertical interpolation of the horizontally averaged SGS TKE and
1120!--          resolved-scale velocity variances and use the interpolated values
1121!--          to calculate the coefficient fs, which is a measure of the ratio
1122!--          of the subgrid-scale turbulent kinetic energy to the total amount
1123!--          of turbulent kinetic energy.
1124             IF ( k == 0 )  THEN
1125                e_mean_int = hom(0,1,8,0)
1126             ELSE
1127                e_mean_int = hom(k,1,8,0) +                                    &
1128                                           ( hom(k+1,1,8,0) - hom(k,1,8,0) ) / &
1129                                           ( zu(k+1) - zu(k) ) *               &
1130                                           ( zv(n) - zu(k) )
1131             ENDIF
1132
1133 !           kw = particles(n)%z / dz
1134             kw = kp-1                                    ! ok for ocean??? ( + offset_ocean_nzt_m1 ???)
1135
1136             IF ( k == 0 )  THEN
1137                aa  = hom(k+1,1,30,0)  * ( zv(n) / &
1138                                         ( 0.5_wp * ( zu(k+1) - zu(k) ) ) )
1139                bb  = hom(k+1,1,31,0)  * ( zv(n) / &
1140                                         ( 0.5_wp * ( zu(k+1) - zu(k) ) ) )
1141                cc  = hom(kw+1,1,32,0) * ( zv(n) / &
1142                                         ( 1.0_wp * ( zw(kw+1) - zw(kw) ) ) )
1143             ELSE
1144                aa  = hom(k,1,30,0) + ( hom(k+1,1,30,0) - hom(k,1,30,0) ) *    &
1145                           ( ( zv(n) - zu(k) ) / ( zu(k+1) - zu(k) ) )
1146                bb  = hom(k,1,31,0) + ( hom(k+1,1,31,0) - hom(k,1,31,0) ) *    &
1147                           ( ( zv(n) - zu(k) ) / ( zu(k+1) - zu(k) ) )
1148                cc  = hom(kw,1,32,0) + ( hom(kw+1,1,32,0)-hom(kw,1,32,0) ) *   &
1149                           ( ( zv(n) - zw(kw) ) / ( zw(kw+1)-zw(kw) ) )
1150             ENDIF
1151
1152             vv_int = ( 1.0_wp / 3.0_wp ) * ( aa + bb + cc )
1153!
1154!--          Needed to avoid NaN particle velocities. The value of 1.0 is just
1155!--          an educated guess for the given case.
1156             IF ( vv_int + ( 2.0_wp / 3.0_wp ) * e_mean_int == 0.0_wp )  THEN
1157                fs_int(n) = 1.0_wp
1158             ELSE
1159                fs_int(n) = ( 2.0_wp / 3.0_wp ) * e_mean_int /                 &
1160                            ( vv_int + ( 2.0_wp / 3.0_wp ) * e_mean_int )
1161             ENDIF
1162
1163          ENDDO
1164       ENDDO
1165
1166       DO  n = 1, number_of_particles
1167
1168         rg(n,1) = random_gauss( iran_part, 5.0_wp )
1169         rg(n,2) = random_gauss( iran_part, 5.0_wp )
1170         rg(n,3) = random_gauss( iran_part, 5.0_wp )
1171
1172       ENDDO
1173
1174       DO  n = 1, number_of_particles
1175!
1176!--       Calculate the Lagrangian timescale according to Weil et al. (2004).
1177          lagr_timescale = ( 4.0_wp * e_int(n) ) / &
1178                           ( 3.0_wp * fs_int(n) * c_0 * diss_int(n) )
1179
1180!
1181!--       Calculate the next particle timestep. dt_gap is the time needed to
1182!--       complete the current LES timestep.
1183          dt_gap = dt_3d - particles(n)%dt_sum
1184          dt_particle(n) = MIN( dt_3d, 0.025_wp * lagr_timescale, dt_gap )
1185
1186!
1187!--       The particle timestep should not be too small in order to prevent
1188!--       the number of particle timesteps of getting too large
1189          IF ( dt_particle(n) < dt_min_part  .AND.  dt_min_part < dt_gap )  THEN
1190             dt_particle(n) = dt_min_part
1191          ENDIF
1192
1193!
1194!--       Calculate the SGS velocity components
1195          IF ( particles(n)%age == 0.0_wp )  THEN
1196!
1197!--          For new particles the SGS components are derived from the SGS
1198!--          TKE. Limit the Gaussian random number to the interval
1199!--          [-5.0*sigma, 5.0*sigma] in order to prevent the SGS velocities
1200!--          from becoming unrealistically large.
1201             particles(n)%rvar1 = SQRT( 2.0_wp * sgs_wfu_part * e_int(n) ) *   &
1202                                  ( rg(n,1) - 1.0_wp )
1203             particles(n)%rvar2 = SQRT( 2.0_wp * sgs_wfv_part * e_int(n) ) *   &
1204                                  ( rg(n,2) - 1.0_wp )
1205             particles(n)%rvar3 = SQRT( 2.0_wp * sgs_wfw_part * e_int(n) ) *   &
1206                                  ( rg(n,3) - 1.0_wp )
1207
1208          ELSE
1209!
1210!--          Restriction of the size of the new timestep: compared to the
1211!--          previous timestep the increase must not exceed 200%
1212
1213             dt_particle_m = particles(n)%age - particles(n)%age_m
1214             IF ( dt_particle(n) > 2.0_wp * dt_particle_m )  THEN
1215                dt_particle(n) = 2.0_wp * dt_particle_m
1216             ENDIF
1217
1218!
1219!--          For old particles the SGS components are correlated with the
1220!--          values from the previous timestep. Random numbers have also to
1221!--          be limited (see above).
1222!--          As negative values for the subgrid TKE are not allowed, the
1223!--          change of the subgrid TKE with time cannot be smaller than
1224!--          -e_int(n)/dt_particle. This value is used as a lower boundary
1225!--          value for the change of TKE
1226
1227             de_dt_min = - e_int(n) / dt_particle(n)
1228
1229             de_dt = ( e_int(n) - particles(n)%e_m ) / dt_particle_m
1230
1231             IF ( de_dt < de_dt_min )  THEN
1232                de_dt = de_dt_min
1233             ENDIF
1234
1235             particles(n)%rvar1 = particles(n)%rvar1 - fs_int(n) * c_0 *       &
1236                           diss_int(n) * particles(n)%rvar1 * dt_particle(n) / &
1237                           ( 4.0_wp * sgs_wfu_part * e_int(n) ) +              &
1238                           ( 2.0_wp * sgs_wfu_part * de_dt *                   &
1239                             particles(n)%rvar1 /                              &
1240                             ( 2.0_wp * sgs_wfu_part * e_int(n) ) +            &
1241                             de_dx_int(n)                                      &
1242                           ) * dt_particle(n) / 2.0_wp          +              &
1243                           SQRT( fs_int(n) * c_0 * diss_int(n) ) *             &
1244                           ( rg(n,1) - 1.0_wp ) *                              &
1245                           SQRT( dt_particle(n) )
1246
1247             particles(n)%rvar2 = particles(n)%rvar2 - fs_int(n) * c_0 *       &
1248                           diss_int(n) * particles(n)%rvar2 * dt_particle(n) / &
1249                           ( 4.0_wp * sgs_wfv_part * e_int(n) ) +              &
1250                           ( 2.0_wp * sgs_wfv_part * de_dt *                   &
1251                             particles(n)%rvar2 /                              &
1252                             ( 2.0_wp * sgs_wfv_part * e_int(n) ) +            &
1253                             de_dy_int(n)                                      &
1254                           ) * dt_particle(n) / 2.0_wp          +              &
1255                           SQRT( fs_int(n) * c_0 * diss_int(n) ) *             &
1256                           ( rg(n,2) - 1.0_wp ) *                              &
1257                           SQRT( dt_particle(n) )
1258
1259             particles(n)%rvar3 = particles(n)%rvar3 - fs_int(n) * c_0 *       &
1260                           diss_int(n) * particles(n)%rvar3 * dt_particle(n) / &
1261                           ( 4.0_wp * sgs_wfw_part * e_int(n) ) +              &
1262                           ( 2.0_wp * sgs_wfw_part * de_dt *                   &
1263                             particles(n)%rvar3 /                              &
1264                             ( 2.0_wp * sgs_wfw_part * e_int(n) ) +            &
1265                             de_dz_int(n)                                      &
1266                           ) * dt_particle(n) / 2.0_wp          +              &
1267                           SQRT( fs_int(n) * c_0 * diss_int(n) ) *             &
1268                           ( rg(n,3) - 1.0_wp ) *                              &
1269                           SQRT( dt_particle(n) )
1270
1271          ENDIF
1272          u_int(n) = u_int(n) + particles(n)%rvar1
1273          v_int(n) = v_int(n) + particles(n)%rvar2
1274          w_int(n) = w_int(n) + particles(n)%rvar3
1275
1276!
1277!--       Store the SGS TKE of the current timelevel which is needed for
1278!--       for calculating the SGS particle velocities at the next timestep
1279          particles(n)%e_m = e_int(n)
1280       ENDDO
1281
1282    ELSE
1283!
1284!--    If no SGS velocities are used, only the particle timestep has to
1285!--    be set
1286       dt_particle = dt_3d
1287
1288    ENDIF
1289!
1290!-- Store the old age of the particle ( needed to prevent that a
1291!-- particle crosses several PEs during one timestep, and for the
1292!-- evaluation of the subgrid particle velocity fluctuations )
1293    particles(1:number_of_particles)%age_m = particles(1:number_of_particles)%age
1294
1295    dens_ratio = particle_groups(particles(1:number_of_particles)%group)%density_ratio
1296
1297    IF ( ANY( dens_ratio == 0.0_wp ) )  THEN
1298       DO  n = 1, number_of_particles
1299
1300!
1301!--       Particle advection
1302          IF ( dens_ratio(n) == 0.0_wp )  THEN
1303!
1304!--          Pure passive transport (without particle inertia)
1305             particles(n)%x = xv(n) + u_int(n) * dt_particle(n)
1306             particles(n)%y = yv(n) + v_int(n) * dt_particle(n)
1307             particles(n)%z = zv(n) + w_int(n) * dt_particle(n)
1308
1309             particles(n)%speed_x = u_int(n)
1310             particles(n)%speed_y = v_int(n)
1311             particles(n)%speed_z = w_int(n)
1312
1313          ELSE
1314!
1315!--          Transport of particles with inertia
1316             particles(n)%x = particles(n)%x + particles(n)%speed_x * &
1317                                               dt_particle(n)
1318             particles(n)%y = particles(n)%y + particles(n)%speed_y * &
1319                                               dt_particle(n)
1320             particles(n)%z = particles(n)%z + particles(n)%speed_z * &
1321                                               dt_particle(n)
1322
1323!
1324!--          Update of the particle velocity
1325             IF ( cloud_droplets )  THEN
1326                exp_arg  = 4.5_wp * dens_ratio(n) * molecular_viscosity /      &
1327                           ( particles(n)%radius )**2 *                        &
1328                           ( 1.0_wp + 0.15_wp * ( 2.0_wp * particles(n)%radius &
1329                             * SQRT( ( u_int(n) - particles(n)%speed_x )**2 +  &
1330                                     ( v_int(n) - particles(n)%speed_y )**2 +  &
1331                                     ( w_int(n) - particles(n)%speed_z )**2 )  &
1332                                          / molecular_viscosity )**0.687_wp    &
1333                           )
1334
1335                exp_term = EXP( -exp_arg * dt_particle(n) )
1336             ELSEIF ( use_sgs_for_particles )  THEN
1337                exp_arg  = particle_groups(particles(n)%group)%exp_arg
1338                exp_term = EXP( -exp_arg * dt_particle(n) )
1339             ELSE
1340                exp_arg  = particle_groups(particles(n)%group)%exp_arg
1341                exp_term = particle_groups(particles(n)%group)%exp_term
1342             ENDIF
1343             particles(n)%speed_x = particles(n)%speed_x * exp_term +          &
1344                                    u_int(n) * ( 1.0_wp - exp_term )
1345             particles(n)%speed_y = particles(n)%speed_y * exp_term +          &
1346                                    v_int(n) * ( 1.0_wp - exp_term )
1347             particles(n)%speed_z = particles(n)%speed_z * exp_term +          &
1348                                    ( w_int(n) - ( 1.0_wp - dens_ratio(n) ) *  &
1349                                    g / exp_arg ) * ( 1.0_wp - exp_term )
1350          ENDIF
1351
1352       ENDDO
1353   
1354    ELSE
1355
1356       DO  n = 1, number_of_particles
1357
1358!--       Transport of particles with inertia
1359          particles(n)%x = xv(n) + particles(n)%speed_x * dt_particle(n)
1360          particles(n)%y = yv(n) + particles(n)%speed_y * dt_particle(n)
1361          particles(n)%z = zv(n) + particles(n)%speed_z * dt_particle(n)
1362!
1363!--       Update of the particle velocity
1364          IF ( cloud_droplets )  THEN
1365
1366             exp_arg  = 4.5_wp * dens_ratio(n) * molecular_viscosity /         &
1367                        ( particles(n)%radius )**2 *                           &
1368                        ( 1.0_wp + 0.15_wp * ( 2.0_wp * particles(n)%radius *  &
1369                          SQRT( ( u_int(n) - particles(n)%speed_x )**2 +       &
1370                                ( v_int(n) - particles(n)%speed_y )**2 +       &
1371                                ( w_int(n) - particles(n)%speed_z )**2 ) /     &
1372                                         molecular_viscosity )**0.687_wp       &
1373                        )
1374
1375             exp_term = EXP( -exp_arg * dt_particle(n) )
1376          ELSEIF ( use_sgs_for_particles )  THEN
1377             exp_arg  = particle_groups(particles(n)%group)%exp_arg
1378             exp_term = EXP( -exp_arg * dt_particle(n) )
1379          ELSE
1380             exp_arg  = particle_groups(particles(n)%group)%exp_arg
1381             exp_term = particle_groups(particles(n)%group)%exp_term
1382          ENDIF
1383          particles(n)%speed_x = particles(n)%speed_x * exp_term +             &
1384                                 u_int(n) * ( 1.0_wp - exp_term )
1385          particles(n)%speed_y = particles(n)%speed_y * exp_term +             &
1386                                 v_int(n) * ( 1.0_wp - exp_term )
1387          particles(n)%speed_z = particles(n)%speed_z * exp_term +             &
1388                                 ( w_int(n) - ( 1.0_wp - dens_ratio(n) ) * g / &
1389                                 exp_arg ) * ( 1.0_wp - exp_term )
1390       ENDDO
1391
1392    ENDIF
1393
1394    DO  n = 1, number_of_particles
1395!
1396!--    Increment the particle age and the total time that the particle
1397!--    has advanced within the particle timestep procedure
1398       particles(n)%age    = particles(n)%age    + dt_particle(n)
1399       particles(n)%dt_sum = particles(n)%dt_sum + dt_particle(n)
1400
1401!
1402!--    Check whether there is still a particle that has not yet completed
1403!--    the total LES timestep
1404       IF ( ( dt_3d - particles(n)%dt_sum ) > 1E-8_wp )  THEN
1405          dt_3d_reached_l = .FALSE.
1406       ENDIF
1407
1408    ENDDO
1409
1410    CALL cpu_log( log_point_s(44), 'lpm_advec', 'pause' )
1411
1412 END SUBROUTINE lpm_advec
Note: See TracBrowser for help on using the repository browser.