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

Last change on this file since 2628 was 2628, checked in by schwenkel, 6 years ago

enable particle advection with grid stretching and some formatation changes in lpm

  • Property svn:keywords set to Id
File size: 80.5 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
6! terms of the GNU General Public License as published by the Free Software
7! Foundation, either version 3 of the License, or (at your option) any later
8! 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-2017 Leibniz Universitaet Hannover
18!------------------------------------------------------------------------------!
19!
20! Current revisions:
21! ------------------
22!  Removed indices ilog and jlog which are no longer needed since particle box
23! locations are identical to scalar boxes and topography.
24
25!
26! Former revisions:
27! -----------------
28! $Id: lpm_advec.f90 2628 2017-11-20 12:40:38Z schwenkel $
29! bugfix in logarithmic interpolation of v-component (usws was used by mistake)
30!
31! 2606 2017-11-10 10:36:31Z schwenkel
32! Changed particle box locations: center of particle box now coincides
33! with scalar grid point of same index.
34! Renamed module and subroutines: lpm_pack_arrays_mod -> lpm_pack_and_sort_mod
35! lpm_pack_all_arrays -> lpm_sort_in_subboxes, lpm_pack_arrays -> lpm_pack
36! lpm_sort -> lpm_sort_timeloop_done
37!
38! 2417 2017-09-06 15:22:27Z suehring
39! Particle loops adapted for sub-box structure, i.e. for each sub-box the
40! particle loop runs from start_index up to end_index instead from 1 to
41! number_of_particles. This way, it is possible to skip unnecessary
42! computations for particles that already completed the LES timestep.
43!
44! 2318 2017-07-20 17:27:44Z suehring
45! Get topography top index via Function call
46!
47! 2317 2017-07-20 17:27:19Z suehring
48!
49! 2232 2017-05-30 17:47:52Z suehring
50! Adjustments to new topography and surface concept
51!
52! 2100 2017-01-05 16:40:16Z suehring
53! Prevent extremely large SGS-velocities in regions where TKE is zero, e.g.
54! at the begin of simulations and/or in non-turbulent regions.
55!
56! 2000 2016-08-20 18:09:15Z knoop
57! Forced header and separation lines into 80 columns
58!
59! 1936 2016-06-13 13:37:44Z suehring
60! Formatting adjustments
61!
62! 1929 2016-06-09 16:25:25Z suehring
63! Put stochastic equation in an extra subroutine.
64! Set flag for stochastic equation to communicate whether a particle is near
65! topography. This case, memory and drift term are disabled in the Weil equation.
66!
67! Enable vertical logarithmic interpolation also above topography. This case,
68! set a lower limit for the friction velocity, as it can become very small
69! in narrow street canyons, leading to too large particle speeds.
70!
71! 1888 2016-04-21 12:20:49Z suehring
72! Bugfix concerning logarithmic interpolation of particle speed
73!
74! 1822 2016-04-07 07:49:42Z hoffmann
75! Random velocity fluctuations for particles added. Terminal fall velocity
76! for droplets is calculated from a parameterization (which is better than
77! the previous, physically correct calculation, which demands a very short
78! time step that is not used in the model).
79!
80! Unused variables deleted.
81!
82! 1691 2015-10-26 16:17:44Z maronga
83! Renamed prandtl_layer to constant_flux_layer.
84!
85! 1685 2015-10-08 07:32:13Z raasch
86! TKE check for negative values (so far, only zero value was checked)
87! offset_ocean_nzt_m1 removed
88!
89! 1682 2015-10-07 23:56:08Z knoop
90! Code annotations made doxygen readable
91!
92! 1583 2015-04-15 12:16:27Z suehring
93! Bugfix: particle advection within Prandtl-layer in case of Galilei
94! transformation.
95!
96! 1369 2014-04-24 05:57:38Z raasch
97! usage of module interfaces removed
98!
99! 1359 2014-04-11 17:15:14Z hoffmann
100! New particle structure integrated.
101! Kind definition added to all floating point numbers.
102!
103! 1322 2014-03-20 16:38:49Z raasch
104! REAL constants defined as wp_kind
105!
106! 1320 2014-03-20 08:40:49Z raasch
107! ONLY-attribute added to USE-statements,
108! kind-parameters added to all INTEGER and REAL declaration statements,
109! kinds are defined in new module kinds,
110! revision history before 2012 removed,
111! comment fields (!:) to be used for variable explanations added to
112! all variable declaration statements
113!
114! 1314 2014-03-14 18:25:17Z suehring
115! Vertical logarithmic interpolation of horizontal particle speed for particles
116! between roughness height and first vertical grid level.
117!
118! 1036 2012-10-22 13:43:42Z raasch
119! code put under GPL (PALM 3.9)
120!
121! 849 2012-03-15 10:35:09Z raasch
122! initial revision (former part of advec_particles)
123!
124!
125! Description:
126! ------------
127!> Calculation of new particle positions due to advection using a simple Euler
128!> scheme. Particles may feel inertia effects. SGS transport can be included
129!> using the stochastic model of Weil et al. (2004, JAS, 61, 2877-2887).
130!------------------------------------------------------------------------------!
131 SUBROUTINE lpm_advec (ip,jp,kp)
132 
133
134    USE arrays_3d,                                                             &
135        ONLY:  de_dx, de_dy, de_dz, diss, e, km, u, v, w, zu, zw
136
137    USE cpulog
138
139    USE pegrid
140
141    USE control_parameters,                                                    &
142        ONLY:  atmos_ocean_sign, cloud_droplets, constant_flux_layer, dt_3d,   &
143               dt_3d_reached_l, dz, g, kappa, topography, u_gtrans, v_gtrans
144
145    USE grid_variables,                                                        &
146        ONLY:  ddx, dx, ddy, dy
147       
148    USE indices,                                                               &
149        ONLY:  nzb, nzt
150       
151    USE kinds
152   
153    USE particle_attributes,                                                   &
154        ONLY:  block_offset, c_0, dt_min_part, grid_particles,                 &
155               iran_part, log_z_z0, number_of_particles, number_of_sublayers,  &
156               particles, particle_groups, offset_ocean_nzt, sgs_wf_part,      &
157               use_sgs_for_particles, vertical_particle_advection, z0_av_global
158       
159    USE statistics,                                                            &
160        ONLY:  hom
161
162    USE surface_mod,                                                           &
163        ONLY:  get_topography_top_index, surf_def_h, surf_lsm_h, surf_usm_h
164
165    IMPLICIT NONE
166
167    INTEGER(iwp) ::  agp                         !< loop variable
168    INTEGER(iwp) ::  gp_outside_of_building(1:8) !< number of grid points used for particle interpolation in case of topography
169    INTEGER(iwp) ::  i                           !< index variable along x
170    INTEGER(iwp) ::  ip                          !< index variable along x
171    INTEGER(iwp) ::  j                           !< index variable along y
172    INTEGER(iwp) ::  jp                          !< index variable along y
173    INTEGER(iwp) ::  k                           !< index variable along z
174    INTEGER(iwp) ::  k_wall                      !< vertical index of topography top
175    INTEGER(iwp) ::  kp                          !< index variable along z
176    INTEGER(iwp) ::  kw                          !< index variable along z
177    INTEGER(iwp) ::  n                           !< loop variable over all particles in a grid box
178    INTEGER(iwp) ::  nb                          !< block number particles are sorted in
179    INTEGER(iwp) ::  num_gp                      !< number of adjacent grid points inside topography
180    INTEGER(iwp) ::  surf_start                  !< Index on surface data-type for current grid box
181
182    INTEGER(iwp), DIMENSION(0:7) ::  start_index !< start particle index for current block
183    INTEGER(iwp), DIMENSION(0:7) ::  end_index   !< start particle index for current block
184
185    REAL(wp) ::  aa                 !< dummy argument for horizontal particle interpolation
186    REAL(wp) ::  bb                 !< dummy argument for horizontal particle interpolation
187    REAL(wp) ::  cc                 !< dummy argument for horizontal particle interpolation
188    REAL(wp) ::  d_sum              !< dummy argument for horizontal particle interpolation in case of topography
189    REAL(wp) ::  d_z_p_z0           !< inverse of interpolation length for logarithmic interpolation
190    REAL(wp) ::  dd                 !< dummy argument for horizontal particle interpolation
191    REAL(wp) ::  de_dx_int_l        !< x/y-interpolated TKE gradient (x) at particle position at lower vertical level
192    REAL(wp) ::  de_dx_int_u        !< x/y-interpolated TKE gradient (x) at particle position at upper vertical level
193    REAL(wp) ::  de_dy_int_l        !< x/y-interpolated TKE gradient (y) at particle position at lower vertical level
194    REAL(wp) ::  de_dy_int_u        !< x/y-interpolated TKE gradient (y) at particle position at upper vertical level
195    REAL(wp) ::  de_dt              !< temporal derivative of TKE experienced by the particle
196    REAL(wp) ::  de_dt_min          !< lower level for temporal TKE derivative
197    REAL(wp) ::  de_dz_int_l        !< x/y-interpolated TKE gradient (z) at particle position at lower vertical level
198    REAL(wp) ::  de_dz_int_u        !< x/y-interpolated TKE gradient (z) at particle position at upper vertical level
199    REAL(wp) ::  diameter           !< diamter of droplet
200    REAL(wp) ::  diss_int_l         !< x/y-interpolated dissipation at particle position at lower vertical level
201    REAL(wp) ::  diss_int_u         !< x/y-interpolated dissipation at particle position at upper vertical level
202    REAL(wp) ::  dt_gap             !< remaining time until particle time integration reaches LES time
203    REAL(wp) ::  dt_particle_m      !< previous particle time step
204    REAL(wp) ::  e_int_l            !< x/y-interpolated TKE at particle position at lower vertical level
205    REAL(wp) ::  e_int_u            !< x/y-interpolated TKE at particle position at upper vertical level
206    REAL(wp) ::  e_mean_int         !< horizontal mean TKE at particle height
207    REAL(wp) ::  exp_arg            !<
208    REAL(wp) ::  exp_term           !<
209    REAL(wp) ::  gg                 !< dummy argument for horizontal particle interpolation
210    REAL(wp) ::  height_p           !< dummy argument for logarithmic interpolation
211    REAL(wp) ::  lagr_timescale     !< Lagrangian timescale
212    REAL(wp) ::  location(1:30,1:3) !< wall locations
213    REAL(wp) ::  log_z_z0_int       !< logarithmus used for surface_layer interpolation
214    REAL(wp) ::  random_gauss       !<
215    REAL(wp) ::  RL                 !< Lagrangian autocorrelation coefficient
216    REAL(wp) ::  rg1                !< Gaussian distributed random number
217    REAL(wp) ::  rg2                !< Gaussian distributed random number
218    REAL(wp) ::  rg3                !< Gaussian distributed random number
219    REAL(wp) ::  sigma              !< velocity standard deviation
220    REAL(wp) ::  u_int_l            !< x/y-interpolated u-component at particle position at lower vertical level
221    REAL(wp) ::  u_int_u            !< x/y-interpolated u-component at particle position at upper vertical level
222    REAL(wp) ::  us_int             !< friction velocity at particle grid box
223    REAL(wp) ::  usws_int           !< surface momentum flux (u component) at particle grid box
224    REAL(wp) ::  v_int_l            !< x/y-interpolated v-component at particle position at lower vertical level
225    REAL(wp) ::  v_int_u            !< x/y-interpolated v-component at particle position at upper vertical level
226    REAL(wp) ::  vsws_int           !< surface momentum flux (u component) at particle grid box
227    REAL(wp) ::  vv_int             !<
228    REAL(wp) ::  w_int_l            !< x/y-interpolated w-component at particle position at lower vertical level
229    REAL(wp) ::  w_int_u            !< x/y-interpolated w-component at particle position at upper vertical level
230    REAL(wp) ::  w_s                !< terminal velocity of droplets
231    REAL(wp) ::  x                  !< dummy argument for horizontal particle interpolation
232    REAL(wp) ::  y                  !< dummy argument for horizontal particle interpolation
233    REAL(wp) ::  z_p                !< surface layer height (0.5 dz)
234
235    REAL(wp), PARAMETER ::  a_rog = 9.65_wp      !< parameter for fall velocity
236    REAL(wp), PARAMETER ::  b_rog = 10.43_wp     !< parameter for fall velocity
237    REAL(wp), PARAMETER ::  c_rog = 0.6_wp       !< parameter for fall velocity
238    REAL(wp), PARAMETER ::  k_cap_rog = 4.0_wp   !< parameter for fall velocity
239    REAL(wp), PARAMETER ::  k_low_rog = 12.0_wp  !< parameter for fall velocity
240    REAL(wp), PARAMETER ::  d0_rog = 0.745_wp    !< separation diameter
241
242    REAL(wp), DIMENSION(1:30) ::  d_gp_pl !< dummy argument for particle interpolation scheme in case of topography
243    REAL(wp), DIMENSION(1:30) ::  de_dxi  !< horizontal TKE gradient along x at adjacent wall
244    REAL(wp), DIMENSION(1:30) ::  de_dyi  !< horizontal TKE gradient along y at adjacent wall
245    REAL(wp), DIMENSION(1:30) ::  de_dzi  !< horizontal TKE gradient along z at adjacent wall
246    REAL(wp), DIMENSION(1:30) ::  dissi   !< dissipation at adjacent wall
247    REAL(wp), DIMENSION(1:30) ::  ei      !< TKE at adjacent wall
248
249    REAL(wp), DIMENSION(number_of_particles) ::  term_1_2     !< flag to communicate whether a particle is near topography or not
250    REAL(wp), DIMENSION(number_of_particles) ::  dens_ratio   !<
251    REAL(wp), DIMENSION(number_of_particles) ::  de_dx_int    !< horizontal TKE gradient along x at particle position
252    REAL(wp), DIMENSION(number_of_particles) ::  de_dy_int    !< horizontal TKE gradient along y at particle position
253    REAL(wp), DIMENSION(number_of_particles) ::  de_dz_int    !< horizontal TKE gradient along z at particle position
254    REAL(wp), DIMENSION(number_of_particles) ::  diss_int     !< dissipation at particle position
255    REAL(wp), DIMENSION(number_of_particles) ::  dt_particle  !< particle time step
256    REAL(wp), DIMENSION(number_of_particles) ::  e_int        !< TKE at particle position
257    REAL(wp), DIMENSION(number_of_particles) ::  fs_int       !< weighting factor for subgrid-scale particle speed
258    REAL(wp), DIMENSION(number_of_particles) ::  u_int        !< u-component of particle speed
259    REAL(wp), DIMENSION(number_of_particles) ::  v_int        !< v-component of particle speed
260    REAL(wp), DIMENSION(number_of_particles) ::  w_int        !< w-component of particle speed
261    REAL(wp), DIMENSION(number_of_particles) ::  xv           !< x-position
262    REAL(wp), DIMENSION(number_of_particles) ::  yv           !< y-position
263    REAL(wp), DIMENSION(number_of_particles) ::  zv           !< z-position
264
265    REAL(wp), DIMENSION(number_of_particles, 3) ::  rg !< vector of Gaussian distributed random numbers
266
267    CALL cpu_log( log_point_s(44), 'lpm_advec', 'continue' )
268
269!
270!-- Determine height of Prandtl layer and distance between Prandtl-layer
271!-- height and horizontal mean roughness height, which are required for
272!-- vertical logarithmic interpolation of horizontal particle speeds
273!-- (for particles below first vertical grid level).
274    z_p      = zu(nzb+1) - zw(nzb)
275    d_z_p_z0 = 1.0_wp / ( z_p - z0_av_global )
276
277    start_index = grid_particles(kp,jp,ip)%start_index
278    end_index   = grid_particles(kp,jp,ip)%end_index
279
280    xv = particles(1:number_of_particles)%x
281    yv = particles(1:number_of_particles)%y
282    zv = particles(1:number_of_particles)%z
283
284    DO  nb = 0, 7
285!
286!--    Interpolate u velocity-component       
287       i = ip
288       j = jp + block_offset(nb)%j_off
289       k = kp + block_offset(nb)%k_off
290
291       DO  n = start_index(nb), end_index(nb)
292!
293!--       Interpolation of the u velocity component onto particle position. 
294!--       Particles are interpolation bi-linearly in the horizontal and a
295!--       linearly in the vertical. An exception is made for particles below
296!--       the first vertical grid level in case of a prandtl layer. In this
297!--       case the horizontal particle velocity components are determined using
298!--       Monin-Obukhov relations (if branch).
299!--       First, check if particle is located below first vertical grid level
300!--       above topography (Prandtl-layer height)
301!--       Determine vertical index of topography top
302          k_wall = get_topography_top_index( jp, ip, 's' )
303
304          IF ( constant_flux_layer  .AND.  zv(n) - zw(k_wall) < z_p )  THEN
305!
306!--          Resolved-scale horizontal particle velocity is zero below z0.
307             IF ( zv(n) - zw(k_wall) < z0_av_global )  THEN
308                u_int(n) = 0.0_wp
309             ELSE
310!
311!--             Determine the sublayer. Further used as index.
312                height_p = ( zv(n) - zw(k_wall) - z0_av_global ) &
313                                     * REAL( number_of_sublayers, KIND=wp )    &
314                                     * d_z_p_z0 
315!
316!--             Calculate LOG(z/z0) for exact particle height. Therefore,   
317!--             interpolate linearly between precalculated logarithm.
318                log_z_z0_int = log_z_z0(INT(height_p))                         &
319                                 + ( height_p - INT(height_p) )                &
320                                 * ( log_z_z0(INT(height_p)+1)                 &
321                                      - log_z_z0(INT(height_p))                &
322                                   ) 
323!
324!--             Get friction velocity and momentum flux from new surface data
325!--             types.
326                IF ( surf_def_h(0)%start_index(jp,ip) <=                   &
327                     surf_def_h(0)%end_index(jp,ip) )  THEN
328                   surf_start = surf_def_h(0)%start_index(jp,ip)
329!--                Limit friction velocity. In narrow canyons or holes the
330!--                friction velocity can become very small, resulting in a too
331!--                large particle speed.
332                   us_int    = MAX( surf_def_h(0)%us(surf_start), 0.01_wp ) 
333                   usws_int  = surf_def_h(0)%usws(surf_start)
334                ELSEIF ( surf_lsm_h%start_index(jp,ip) <=                  &
335                         surf_lsm_h%end_index(jp,ip) )  THEN
336                   surf_start = surf_lsm_h%start_index(jp,ip)
337                   us_int    = MAX( surf_lsm_h%us(surf_start), 0.01_wp ) 
338                   usws_int  = surf_lsm_h%usws(surf_start)
339                ELSEIF ( surf_usm_h%start_index(jp,ip) <=                  &
340                         surf_usm_h%end_index(jp,ip) )  THEN
341                   surf_start = surf_usm_h%start_index(jp,ip)
342                   us_int    = MAX( surf_usm_h%us(surf_start), 0.01_wp ) 
343                   usws_int  = surf_usm_h%usws(surf_start)
344                ENDIF
345
346!
347!--             Neutral solution is applied for all situations, e.g. also for
348!--             unstable and stable situations. Even though this is not exact
349!--             this saves a lot of CPU time since several calls of intrinsic
350!--             FORTRAN procedures (LOG, ATAN) are avoided, This is justified
351!--             as sensitivity studies revealed no significant effect of
352!--             using the neutral solution also for un/stable situations.
353                u_int(n) = -usws_int / ( us_int * kappa + 1E-10_wp )           & 
354                            * log_z_z0_int - u_gtrans
355               
356             ENDIF
357!
358!--       Particle above the first grid level. Bi-linear interpolation in the
359!--       horizontal and linear interpolation in the vertical direction.
360          ELSE
361
362             x  = xv(n) + ( 0.5_wp - i ) * dx
363             y  = yv(n) - j * dy
364             aa = x**2          + y**2
365             bb = ( dx - x )**2 + y**2
366             cc = x**2          + ( dy - y )**2
367             dd = ( dx - x )**2 + ( dy - y )**2
368             gg = aa + bb + cc + dd
369
370             u_int_l = ( ( gg - aa ) * u(k,j,i)   + ( gg - bb ) * u(k,j,i+1)   &
371                         + ( gg - cc ) * u(k,j+1,i) + ( gg - dd ) *            &
372                         u(k,j+1,i+1) ) / ( 3.0_wp * gg ) - u_gtrans
373
374             IF ( k == nzt )  THEN
375                u_int(n) = u_int_l
376             ELSE
377                u_int_u = ( ( gg-aa ) * u(k+1,j,i) + ( gg-bb ) * u(k+1,j,i+1)  &
378                            + ( gg-cc ) * u(k+1,j+1,i) + ( gg-dd ) *           &
379                            u(k+1,j+1,i+1) ) / ( 3.0_wp * gg ) - u_gtrans
380                u_int(n) = u_int_l + ( zv(n) - zu(k) ) / dz *                  &
381                           ( u_int_u - u_int_l )
382             ENDIF
383
384          ENDIF
385
386       ENDDO
387!
388!--    Same procedure for interpolation of the v velocity-component
389       i = ip + block_offset(nb)%i_off
390       j = jp
391       k = kp + block_offset(nb)%k_off
392
393       DO  n = start_index(nb), end_index(nb)
394
395!
396!--       Determine vertical index of topography top
397          k_wall = get_topography_top_index( jp,ip, 's' )
398
399          IF ( constant_flux_layer  .AND.  zv(n) - zw(k_wall) < z_p )  THEN
400             IF ( zv(n) - zw(k_wall) < z0_av_global )  THEN
401!
402!--             Resolved-scale horizontal particle velocity is zero below z0.
403                v_int(n) = 0.0_wp
404             ELSE       
405!
406!--             Determine the sublayer. Further used as index. Please note,
407!--             logarithmus can not be reused from above, as in in case of
408!--             topography particle on u-grid can be above surface-layer height,
409!--             whereas it can be below on v-grid.
410                height_p = ( zv(n) - zw(k_wall) - z0_av_global ) &
411                                  * REAL( number_of_sublayers, KIND=wp )       &
412                                  * d_z_p_z0 
413!
414!--             Calculate LOG(z/z0) for exact particle height. Therefore,   
415!--             interpolate linearly between precalculated logarithm.
416                log_z_z0_int = log_z_z0(INT(height_p))                         &
417                                 + ( height_p - INT(height_p) )                &
418                                 * ( log_z_z0(INT(height_p)+1)                 &
419                                      - log_z_z0(INT(height_p))                &
420                                   ) 
421!
422!--             Get friction velocity and momentum flux from new surface data
423!--             types.
424                IF ( surf_def_h(0)%start_index(jp,ip) <=                   &
425                     surf_def_h(0)%end_index(jp,ip) )  THEN
426                   surf_start = surf_def_h(0)%start_index(jp,ip)
427!--                Limit friction velocity. In narrow canyons or holes the
428!--                friction velocity can become very small, resulting in a too
429!--                large particle speed.
430                   us_int    = MAX( surf_def_h(0)%us(surf_start), 0.01_wp ) 
431                   vsws_int  = surf_def_h(0)%vsws(surf_start)
432                ELSEIF ( surf_lsm_h%start_index(jp,ip) <=                  &
433                         surf_lsm_h%end_index(jp,ip) )  THEN
434                   surf_start = surf_lsm_h%start_index(jp,ip)
435                   us_int    = MAX( surf_lsm_h%us(surf_start), 0.01_wp ) 
436                   vsws_int  = surf_lsm_h%vsws(surf_start)
437                ELSEIF ( surf_usm_h%start_index(jp,ip) <=                  &
438                         surf_usm_h%end_index(jp,ip) )  THEN
439                   surf_start = surf_usm_h%start_index(jp,ip)
440                   us_int    = MAX( surf_usm_h%us(surf_start), 0.01_wp ) 
441                   vsws_int  = surf_usm_h%vsws(surf_start)
442                ENDIF 
443!
444!--             Neutral solution is applied for all situations, e.g. also for
445!--             unstable and stable situations. Even though this is not exact
446!--             this saves a lot of CPU time since several calls of intrinsic
447!--             FORTRAN procedures (LOG, ATAN) are avoided, This is justified
448!--             as sensitivity studies revealed no significant effect of
449!--             using the neutral solution also for un/stable situations.
450                v_int(n) = -vsws_int / ( us_int * kappa + 1E-10_wp )           &
451                         * log_z_z0_int - v_gtrans
452
453             ENDIF
454
455          ELSE
456             x  = xv(n) - i * dx
457             y  = yv(n) + ( 0.5_wp - j ) * dy
458             aa = x**2          + y**2
459             bb = ( dx - x )**2 + y**2
460             cc = x**2          + ( dy - y )**2
461             dd = ( dx - x )**2 + ( dy - y )**2
462             gg = aa + bb + cc + dd
463
464             v_int_l = ( ( gg - aa ) * v(k,j,i)   + ( gg - bb ) * v(k,j,i+1)   &
465                       + ( gg - cc ) * v(k,j+1,i) + ( gg - dd ) * v(k,j+1,i+1) &
466                       ) / ( 3.0_wp * gg ) - v_gtrans
467
468             IF ( k == nzt )  THEN
469                v_int(n) = v_int_l
470             ELSE
471                v_int_u = ( ( gg-aa ) * v(k+1,j,i)   + ( gg-bb ) * v(k+1,j,i+1)   &
472                          + ( gg-cc ) * v(k+1,j+1,i) + ( gg-dd ) * v(k+1,j+1,i+1) &
473                          ) / ( 3.0_wp * gg ) - v_gtrans
474                v_int(n) = v_int_l + ( zv(n) - zu(k) ) / dz * &
475                                  ( v_int_u - v_int_l )
476             ENDIF
477
478          ENDIF
479
480       ENDDO
481!
482!--    Same procedure for interpolation of the w velocity-component
483       i = ip + block_offset(nb)%i_off
484       j = jp + block_offset(nb)%j_off
485       k = kp - 1
486
487       DO  n = start_index(nb), end_index(nb)
488
489          IF ( vertical_particle_advection(particles(n)%group) )  THEN
490
491             x  = xv(n) - i * dx
492             y  = yv(n) - j * dy
493             aa = x**2          + y**2
494             bb = ( dx - x )**2 + y**2
495             cc = x**2          + ( dy - y )**2
496             dd = ( dx - x )**2 + ( dy - y )**2
497             gg = aa + bb + cc + dd
498
499             w_int_l = ( ( gg - aa ) * w(k,j,i)   + ( gg - bb ) * w(k,j,i+1)   &
500                       + ( gg - cc ) * w(k,j+1,i) + ( gg - dd ) * w(k,j+1,i+1) &
501                       ) / ( 3.0_wp * gg )
502
503             IF ( k == nzt )  THEN
504                w_int(n) = w_int_l
505             ELSE
506                w_int_u = ( ( gg-aa ) * w(k+1,j,i)   + &
507                            ( gg-bb ) * w(k+1,j,i+1) + &
508                            ( gg-cc ) * w(k+1,j+1,i) + &
509                            ( gg-dd ) * w(k+1,j+1,i+1) &
510                          ) / ( 3.0_wp * gg )
511                w_int(n) = w_int_l + ( zv(n) - zw(k) ) / dz * &
512                           ( w_int_u - w_int_l )
513             ENDIF
514
515          ELSE
516
517             w_int(n) = 0.0_wp
518
519          ENDIF
520
521       ENDDO
522
523    ENDDO
524
525!-- Interpolate and calculate quantities needed for calculating the SGS
526!-- velocities
527    IF ( use_sgs_for_particles  .AND.  .NOT. cloud_droplets )  THEN
528
529       IF ( topography == 'flat' )  THEN
530
531          DO  nb = 0,7
532
533             i = ip + block_offset(nb)%i_off
534             j = jp + block_offset(nb)%j_off
535             k = kp + block_offset(nb)%k_off
536
537             DO  n = start_index(nb), end_index(nb)
538!
539!--             Interpolate TKE
540                x  = xv(n) - i * dx
541                y  = yv(n) - j * dy
542                aa = x**2          + y**2
543                bb = ( dx - x )**2 + y**2
544                cc = x**2          + ( dy - y )**2
545                dd = ( dx - x )**2 + ( dy - y )**2
546                gg = aa + bb + cc + dd
547
548                e_int_l = ( ( gg-aa ) * e(k,j,i)   + ( gg-bb ) * e(k,j,i+1)   &
549                          + ( gg-cc ) * e(k,j+1,i) + ( gg-dd ) * e(k,j+1,i+1) &
550                          ) / ( 3.0_wp * gg )
551
552                IF ( k+1 == nzt+1 )  THEN
553                   e_int(n) = e_int_l
554                ELSE
555                   e_int_u = ( ( gg - aa ) * e(k+1,j,i)   + &
556                               ( gg - bb ) * e(k+1,j,i+1) + &
557                               ( gg - cc ) * e(k+1,j+1,i) + &
558                               ( gg - dd ) * e(k+1,j+1,i+1) &
559                            ) / ( 3.0_wp * gg )
560                   e_int(n) = e_int_l + ( zv(n) - zu(k) ) / dz * &
561                                     ( e_int_u - e_int_l )
562                ENDIF
563!
564!--             Needed to avoid NaN particle velocities (this might not be
565!--             required any more)
566                IF ( e_int(n) <= 0.0_wp )  THEN
567                   e_int(n) = 1.0E-20_wp
568                ENDIF
569!
570!--             Interpolate the TKE gradient along x (adopt incides i,j,k and
571!--             all position variables from above (TKE))
572                de_dx_int_l = ( ( gg - aa ) * de_dx(k,j,i)   + &
573                                ( gg - bb ) * de_dx(k,j,i+1) + &
574                                ( gg - cc ) * de_dx(k,j+1,i) + &
575                                ( gg - dd ) * de_dx(k,j+1,i+1) &
576                               ) / ( 3.0_wp * gg )
577
578                IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
579                   de_dx_int(n) = de_dx_int_l
580                ELSE
581                   de_dx_int_u = ( ( gg - aa ) * de_dx(k+1,j,i)   + &
582                                   ( gg - bb ) * de_dx(k+1,j,i+1) + &
583                                   ( gg - cc ) * de_dx(k+1,j+1,i) + &
584                                   ( gg - dd ) * de_dx(k+1,j+1,i+1) &
585                                  ) / ( 3.0_wp * gg )
586                   de_dx_int(n) = de_dx_int_l + ( zv(n) - zu(k) ) / dz * &
587                                              ( de_dx_int_u - de_dx_int_l )
588                ENDIF
589!
590!--             Interpolate the TKE gradient along y
591                de_dy_int_l = ( ( gg - aa ) * de_dy(k,j,i)   + &
592                                ( gg - bb ) * de_dy(k,j,i+1) + &
593                                ( gg - cc ) * de_dy(k,j+1,i) + &
594                                ( gg - dd ) * de_dy(k,j+1,i+1) &
595                               ) / ( 3.0_wp * gg )
596                IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
597                   de_dy_int(n) = de_dy_int_l
598                ELSE
599                   de_dy_int_u = ( ( gg - aa ) * de_dy(k+1,j,i)   + &
600                                  ( gg - bb ) * de_dy(k+1,j,i+1) + &
601                                  ( gg - cc ) * de_dy(k+1,j+1,i) + &
602                                  ( gg - dd ) * de_dy(k+1,j+1,i+1) &
603                                  ) / ( 3.0_wp * gg )
604                   de_dy_int(n) = de_dy_int_l + ( zv(n) - zu(k) ) / dz * &
605                                              ( de_dy_int_u - de_dy_int_l )
606                ENDIF
607
608!
609!--             Interpolate the TKE gradient along z
610                IF ( zv(n) < 0.5_wp * dz )  THEN
611                   de_dz_int(n) = 0.0_wp
612                ELSE
613                   de_dz_int_l = ( ( gg - aa ) * de_dz(k,j,i)   + &
614                                   ( gg - bb ) * de_dz(k,j,i+1) + &
615                                   ( gg - cc ) * de_dz(k,j+1,i) + &
616                                   ( gg - dd ) * de_dz(k,j+1,i+1) &
617                                  ) / ( 3.0_wp * gg )
618
619                   IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
620                      de_dz_int(n) = de_dz_int_l
621                   ELSE
622                      de_dz_int_u = ( ( gg - aa ) * de_dz(k+1,j,i)   + &
623                                      ( gg - bb ) * de_dz(k+1,j,i+1) + &
624                                      ( gg - cc ) * de_dz(k+1,j+1,i) + &
625                                      ( gg - dd ) * de_dz(k+1,j+1,i+1) &
626                                     ) / ( 3.0_wp * gg )
627                      de_dz_int(n) = de_dz_int_l + ( zv(n) - zu(k) ) / dz * &
628                                                 ( de_dz_int_u - de_dz_int_l )
629                   ENDIF
630                ENDIF
631
632!
633!--             Interpolate the dissipation of TKE
634                diss_int_l = ( ( gg - aa ) * diss(k,j,i)   + &
635                               ( gg - bb ) * diss(k,j,i+1) + &
636                               ( gg - cc ) * diss(k,j+1,i) + &
637                               ( gg - dd ) * diss(k,j+1,i+1) &
638                              ) / ( 3.0_wp * gg )
639
640                IF ( k == nzt )  THEN
641                   diss_int(n) = diss_int_l
642                ELSE
643                   diss_int_u = ( ( gg - aa ) * diss(k+1,j,i)   + &
644                                  ( gg - bb ) * diss(k+1,j,i+1) + &
645                                  ( gg - cc ) * diss(k+1,j+1,i) + &
646                                  ( gg - dd ) * diss(k+1,j+1,i+1) &
647                                 ) / ( 3.0_wp * gg )
648                   diss_int(n) = diss_int_l + ( zv(n) - zu(k) ) / dz * &
649                                           ( diss_int_u - diss_int_l )
650                ENDIF
651
652!
653!--             Set flag for stochastic equation.
654                term_1_2(n) = 1.0_wp
655
656             ENDDO
657          ENDDO
658
659       ELSE ! non-flat topography, e.g., buildings
660
661          DO  nb = 0, 7
662
663             DO  n = start_index(nb), end_index(nb)
664
665                i = particles(n)%x * ddx
666                j = particles(n)%y * ddy
667                k = ( zv(n) + dz * atmos_ocean_sign ) / dz  &
668                    + offset_ocean_nzt                      ! only exact if eq.dist
669!
670!--             In case that there are buildings it has to be determined
671!--             how many of the gridpoints defining the particle box are
672!--             situated within a building
673!--             gp_outside_of_building(1): i,j,k
674!--             gp_outside_of_building(2): i,j+1,k
675!--             gp_outside_of_building(3): i,j,k+1
676!--             gp_outside_of_building(4): i,j+1,k+1
677!--             gp_outside_of_building(5): i+1,j,k
678!--             gp_outside_of_building(6): i+1,j+1,k
679!--             gp_outside_of_building(7): i+1,j,k+1
680!--             gp_outside_of_building(8): i+1,j+1,k+1
681
682                gp_outside_of_building = 0
683                location = 0.0_wp
684                num_gp = 0
685
686!
687!--             Determine vertical index of topography top at (j,i)
688                k_wall = get_topography_top_index( j, i, 's' )
689!
690!--             To do: Reconsider order of computations in order to avoid
691!--             unnecessary index calculations.
692                IF ( k > k_wall  .OR.  k_wall == 0 )  THEN
693                   num_gp = num_gp + 1
694                   gp_outside_of_building(1) = 1
695                   location(num_gp,1) = i * dx
696                   location(num_gp,2) = j * dy
697                   location(num_gp,3) = k * dz - 0.5_wp * dz
698                   ei(num_gp)     = e(k,j,i)
699                   dissi(num_gp)  = diss(k,j,i)
700                   de_dxi(num_gp) = de_dx(k,j,i)
701                   de_dyi(num_gp) = de_dy(k,j,i)
702                   de_dzi(num_gp) = de_dz(k,j,i)
703                ENDIF
704
705!
706!--             Determine vertical index of topography top at (j+1,i)
707                k_wall = get_topography_top_index( j+1, i, 's' )
708
709                IF ( k > k_wall  .OR.  k_wall == 0 )  THEN
710                   num_gp = num_gp + 1
711                   gp_outside_of_building(2) = 1
712                   location(num_gp,1) = i * dx
713                   location(num_gp,2) = (j+1) * dy
714                   location(num_gp,3) = k * dz - 0.5_wp * dz
715                   ei(num_gp)     = e(k,j+1,i)
716                   dissi(num_gp)  = diss(k,j+1,i)
717                   de_dxi(num_gp) = de_dx(k,j+1,i)
718                   de_dyi(num_gp) = de_dy(k,j+1,i)
719                   de_dzi(num_gp) = de_dz(k,j+1,i)
720                ENDIF
721
722!
723!--             Determine vertical index of topography top at (j,i)
724                k_wall = get_topography_top_index( j, i, 's' )
725
726                IF ( k+1 > k_wall  .OR.  k_wall == 0 )  THEN
727                   num_gp = num_gp + 1
728                   gp_outside_of_building(3) = 1
729                   location(num_gp,1) = i * dx
730                   location(num_gp,2) = j * dy
731                   location(num_gp,3) = (k+1) * dz - 0.5_wp * dz
732                   ei(num_gp)     = e(k+1,j,i)
733                   dissi(num_gp)  = diss(k+1,j,i)
734                   de_dxi(num_gp) = de_dx(k+1,j,i)
735                   de_dyi(num_gp) = de_dy(k+1,j,i)
736                   de_dzi(num_gp) = de_dz(k+1,j,i)
737                ENDIF
738
739!
740!--             Determine vertical index of topography top at (j+1,i)
741                k_wall = get_topography_top_index( j+1, i, 's' )
742                IF ( k+1 > k_wall  .OR.  k_wall == 0 )  THEN
743                   num_gp = num_gp + 1
744                   gp_outside_of_building(4) = 1
745                   location(num_gp,1) = i * dx
746                   location(num_gp,2) = (j+1) * dy
747                   location(num_gp,3) = (k+1) * dz - 0.5_wp * dz
748                   ei(num_gp)     = e(k+1,j+1,i)
749                   dissi(num_gp)  = diss(k+1,j+1,i)
750                   de_dxi(num_gp) = de_dx(k+1,j+1,i)
751                   de_dyi(num_gp) = de_dy(k+1,j+1,i)
752                   de_dzi(num_gp) = de_dz(k+1,j+1,i)
753                ENDIF
754
755!
756!--             Determine vertical index of topography top at (j,i+1)
757                k_wall = get_topography_top_index( j, i+1, 's' )
758                IF ( k > k_wall  .OR.  k_wall == 0 )  THEN
759                   num_gp = num_gp + 1
760                   gp_outside_of_building(5) = 1
761                   location(num_gp,1) = (i+1) * dx
762                   location(num_gp,2) = j * dy
763                   location(num_gp,3) = k * dz - 0.5_wp * dz
764                   ei(num_gp)     = e(k,j,i+1)
765                   dissi(num_gp)  = diss(k,j,i+1)
766                   de_dxi(num_gp) = de_dx(k,j,i+1)
767                   de_dyi(num_gp) = de_dy(k,j,i+1)
768                   de_dzi(num_gp) = de_dz(k,j,i+1)
769                ENDIF
770
771!
772!--             Determine vertical index of topography top at (j+1,i+1)
773                k_wall = get_topography_top_index( j+1, i+1, 's' )
774
775                IF ( k > k_wall  .OR.  k_wall == 0 )  THEN
776                   num_gp = num_gp + 1
777                   gp_outside_of_building(6) = 1
778                   location(num_gp,1) = (i+1) * dx
779                   location(num_gp,2) = (j+1) * dy
780                   location(num_gp,3) = k * dz - 0.5_wp * dz
781                   ei(num_gp)     = e(k,j+1,i+1)
782                   dissi(num_gp)  = diss(k,j+1,i+1)
783                   de_dxi(num_gp) = de_dx(k,j+1,i+1)
784                   de_dyi(num_gp) = de_dy(k,j+1,i+1)
785                   de_dzi(num_gp) = de_dz(k,j+1,i+1)
786                ENDIF
787
788!
789!--             Determine vertical index of topography top at (j,i+1)
790                k_wall = get_topography_top_index( j, i+1, 's' )
791
792                IF ( k+1 > k_wall  .OR.  k_wall == 0 )  THEN
793                   num_gp = num_gp + 1
794                   gp_outside_of_building(7) = 1
795                   location(num_gp,1) = (i+1) * dx
796                   location(num_gp,2) = j * dy
797                   location(num_gp,3) = (k+1) * dz - 0.5_wp * dz
798                   ei(num_gp)     = e(k+1,j,i+1)
799                   dissi(num_gp)  = diss(k+1,j,i+1)
800                   de_dxi(num_gp) = de_dx(k+1,j,i+1)
801                   de_dyi(num_gp) = de_dy(k+1,j,i+1)
802                   de_dzi(num_gp) = de_dz(k+1,j,i+1)
803                ENDIF
804
805!
806!--             Determine vertical index of topography top at (j+1,i+1)
807                k_wall = get_topography_top_index( j+1, i+1, 's' )
808
809                IF ( k+1 > k_wall  .OR.  k_wall == 0)  THEN
810                   num_gp = num_gp + 1
811                   gp_outside_of_building(8) = 1
812                   location(num_gp,1) = (i+1) * dx
813                   location(num_gp,2) = (j+1) * dy
814                   location(num_gp,3) = (k+1) * dz - 0.5_wp * dz
815                   ei(num_gp)     = e(k+1,j+1,i+1)
816                   dissi(num_gp)  = diss(k+1,j+1,i+1)
817                   de_dxi(num_gp) = de_dx(k+1,j+1,i+1)
818                   de_dyi(num_gp) = de_dy(k+1,j+1,i+1)
819                   de_dzi(num_gp) = de_dz(k+1,j+1,i+1)
820                ENDIF
821!
822!--             If all gridpoints are situated outside of a building, then the
823!--             ordinary interpolation scheme can be used.
824                IF ( num_gp == 8 )  THEN
825
826                   x  = particles(n)%x - i * dx
827                   y  = particles(n)%y - j * dy
828                   aa = x**2          + y**2
829                   bb = ( dx - x )**2 + y**2
830                   cc = x**2          + ( dy - y )**2
831                   dd = ( dx - x )**2 + ( dy - y )**2
832                   gg = aa + bb + cc + dd
833     
834                   e_int_l = ( ( gg - aa ) * e(k,j,i)   + ( gg - bb ) * e(k,j,i+1)   &
835                             + ( gg - cc ) * e(k,j+1,i) + ( gg - dd ) * e(k,j+1,i+1) &
836                             ) / ( 3.0_wp * gg )
837     
838                   IF ( k == nzt )  THEN
839                      e_int(n) = e_int_l
840                   ELSE
841                      e_int_u = ( ( gg - aa ) * e(k+1,j,i)   + &
842                                  ( gg - bb ) * e(k+1,j,i+1) + &
843                                  ( gg - cc ) * e(k+1,j+1,i) + &
844                                  ( gg - dd ) * e(k+1,j+1,i+1) &
845                                ) / ( 3.0_wp * gg )
846                      e_int(n) = e_int_l + ( zv(n) - zu(k) ) / dz * &
847                                          ( e_int_u - e_int_l )
848                   ENDIF
849!
850!--                Needed to avoid NaN particle velocities (this might not be
851!--                required any more)
852                   IF ( e_int(n) <= 0.0_wp )  THEN
853                      e_int(n) = 1.0E-20_wp
854                   ENDIF
855!
856!--                Interpolate the TKE gradient along x (adopt incides i,j,k
857!--                and all position variables from above (TKE))
858                   de_dx_int_l = ( ( gg - aa ) * de_dx(k,j,i)   + &
859                                   ( gg - bb ) * de_dx(k,j,i+1) + &
860                                   ( gg - cc ) * de_dx(k,j+1,i) + &
861                                   ( gg - dd ) * de_dx(k,j+1,i+1) &
862                                 ) / ( 3.0_wp * gg )
863
864                   IF ( ( k == nzt )  .OR.  ( k == nzb ) )  THEN
865                      de_dx_int(n) = de_dx_int_l
866                   ELSE
867                      de_dx_int_u = ( ( gg - aa ) * de_dx(k+1,j,i)   + &
868                                      ( gg - bb ) * de_dx(k+1,j,i+1) + &
869                                      ( gg - cc ) * de_dx(k+1,j+1,i) + &
870                                      ( gg - dd ) * de_dx(k+1,j+1,i+1) &
871                                    ) / ( 3.0_wp * gg )
872                      de_dx_int(n) = de_dx_int_l + ( zv(n) - zu(k) ) / &
873                                              dz * ( de_dx_int_u - de_dx_int_l )
874                   ENDIF
875
876!
877!--                Interpolate the TKE gradient along y
878                   de_dy_int_l = ( ( gg - aa ) * de_dy(k,j,i)   + &
879                                   ( gg - bb ) * de_dy(k,j,i+1) + &
880                                   ( gg - cc ) * de_dy(k,j+1,i) + &
881                                   ( gg - dd ) * de_dy(k,j+1,i+1) &
882                                 ) / ( 3.0_wp * gg )
883                   IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
884                      de_dy_int(n) = de_dy_int_l
885                   ELSE
886                      de_dy_int_u = ( ( gg - aa ) * de_dy(k+1,j,i)   + &
887                                      ( gg - bb ) * de_dy(k+1,j,i+1) + &
888                                      ( gg - cc ) * de_dy(k+1,j+1,i) + &
889                                      ( gg - dd ) * de_dy(k+1,j+1,i+1) &
890                                    ) / ( 3.0_wp * gg )
891                      de_dy_int(n) = de_dy_int_l + ( zv(n) - zu(k) ) / &
892                                              dz * ( de_dy_int_u - de_dy_int_l )
893                   ENDIF
894
895!
896!--                Interpolate the TKE gradient along z
897                   IF ( zv(n) < 0.5_wp * dz )  THEN
898                      de_dz_int(n) = 0.0_wp
899                   ELSE
900                      de_dz_int_l = ( ( gg - aa ) * de_dz(k,j,i)   + &
901                                      ( gg - bb ) * de_dz(k,j,i+1) + &
902                                      ( gg - cc ) * de_dz(k,j+1,i) + &
903                                      ( gg - dd ) * de_dz(k,j+1,i+1) &
904                                    ) / ( 3.0_wp * gg )
905   
906                      IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
907                         de_dz_int(n) = de_dz_int_l
908                      ELSE
909                         de_dz_int_u = ( ( gg - aa ) * de_dz(k+1,j,i)   + &
910                                         ( gg - bb ) * de_dz(k+1,j,i+1) + &
911                                         ( gg - cc ) * de_dz(k+1,j+1,i) + &
912                                         ( gg - dd ) * de_dz(k+1,j+1,i+1) &
913                                       ) / ( 3.0_wp * gg )
914                         de_dz_int(n) = de_dz_int_l + ( zv(n) - zu(k) ) /&
915                                              dz * ( de_dz_int_u - de_dz_int_l )
916                      ENDIF
917                   ENDIF
918
919!
920!--                Interpolate the dissipation of TKE
921                   diss_int_l = ( ( gg - aa ) * diss(k,j,i)   + &
922                                  ( gg - bb ) * diss(k,j,i+1) + &
923                                  ( gg - cc ) * diss(k,j+1,i) + &
924                                  ( gg - dd ) * diss(k,j+1,i+1) &
925                                ) / ( 3.0_wp * gg )
926   
927                   IF ( k == nzt )  THEN
928                      diss_int(n) = diss_int_l
929                   ELSE
930                      diss_int_u = ( ( gg - aa ) * diss(k+1,j,i)   + &
931                                     ( gg - bb ) * diss(k+1,j,i+1) + &
932                                     ( gg - cc ) * diss(k+1,j+1,i) + &
933                                     ( gg - dd ) * diss(k+1,j+1,i+1) &
934                                   ) / ( 3.0_wp * gg )
935                      diss_int(n) = diss_int_l + ( zv(n) - zu(k) ) / dz *&
936                                              ( diss_int_u - diss_int_l )
937                   ENDIF
938!
939!--                Set flag for stochastic equation.
940                   term_1_2(n) = 1.0_wp
941   
942                ELSE
943   
944!
945!--                If wall between gridpoint 1 and gridpoint 5, then
946!--                Neumann boundary condition has to be applied
947                   IF ( gp_outside_of_building(1) == 1  .AND. &
948                        gp_outside_of_building(5) == 0 )  THEN
949                      num_gp = num_gp + 1
950                      location(num_gp,1) = i * dx + 0.5_wp * dx
951                      location(num_gp,2) = j * dy
952                      location(num_gp,3) = k * dz - 0.5_wp * dz
953                      ei(num_gp)     = e(k,j,i)
954                      dissi(num_gp)  = diss(k,j,i)
955                      de_dxi(num_gp) = 0.0_wp
956                      de_dyi(num_gp) = de_dy(k,j,i)
957                      de_dzi(num_gp) = de_dz(k,j,i)
958                   ENDIF
959
960                   IF ( gp_outside_of_building(5) == 1  .AND. &
961                        gp_outside_of_building(1) == 0 )  THEN
962                      num_gp = num_gp + 1
963                      location(num_gp,1) = i * dx + 0.5_wp * dx
964                      location(num_gp,2) = j * dy
965                      location(num_gp,3) = k * dz - 0.5_wp * dz
966                      ei(num_gp)     = e(k,j,i+1)
967                      dissi(num_gp)  = diss(k,j,i+1)
968                      de_dxi(num_gp) = 0.0_wp
969                      de_dyi(num_gp) = de_dy(k,j,i+1)
970                      de_dzi(num_gp) = de_dz(k,j,i+1)
971                   ENDIF
972
973!
974!--                If wall between gridpoint 5 and gridpoint 6, then
975!--                then Neumann boundary condition has to be applied
976                   IF ( gp_outside_of_building(5) == 1  .AND. &
977                        gp_outside_of_building(6) == 0 )  THEN
978                      num_gp = num_gp + 1
979                      location(num_gp,1) = (i+1) * dx
980                      location(num_gp,2) = j * dy + 0.5_wp * dy
981                      location(num_gp,3) = k * dz - 0.5_wp * dz
982                      ei(num_gp)     = e(k,j,i+1)
983                      dissi(num_gp)  = diss(k,j,i+1)
984                      de_dxi(num_gp) = de_dx(k,j,i+1)
985                      de_dyi(num_gp) = 0.0_wp
986                      de_dzi(num_gp) = de_dz(k,j,i+1)
987                   ENDIF
988
989                   IF ( gp_outside_of_building(6) == 1  .AND. &
990                        gp_outside_of_building(5) == 0 )  THEN
991                      num_gp = num_gp + 1
992                      location(num_gp,1) = (i+1) * dx
993                      location(num_gp,2) = j * dy + 0.5_wp * dy
994                      location(num_gp,3) = k * dz - 0.5_wp * dz
995                      ei(num_gp)     = e(k,j+1,i+1)
996                      dissi(num_gp)  = diss(k,j+1,i+1)
997                      de_dxi(num_gp) = de_dx(k,j+1,i+1)
998                      de_dyi(num_gp) = 0.0_wp
999                      de_dzi(num_gp) = de_dz(k,j+1,i+1)
1000                   ENDIF
1001
1002!
1003!--                If wall between gridpoint 2 and gridpoint 6, then
1004!--                Neumann boundary condition has to be applied
1005                   IF ( gp_outside_of_building(2) == 1  .AND. &
1006                        gp_outside_of_building(6) == 0 )  THEN
1007                      num_gp = num_gp + 1
1008                      location(num_gp,1) = i * dx + 0.5_wp * dx
1009                      location(num_gp,2) = (j+1) * dy
1010                      location(num_gp,3) = k * dz - 0.5_wp * dz
1011                      ei(num_gp)     = e(k,j+1,i)
1012                      dissi(num_gp)  = diss(k,j+1,i)
1013                      de_dxi(num_gp) = 0.0_wp
1014                      de_dyi(num_gp) = de_dy(k,j+1,i)
1015                      de_dzi(num_gp) = de_dz(k,j+1,i)
1016                   ENDIF
1017
1018                   IF ( gp_outside_of_building(6) == 1  .AND. &
1019                        gp_outside_of_building(2) == 0 )  THEN
1020                      num_gp = num_gp + 1
1021                      location(num_gp,1) = i * dx + 0.5_wp * dx
1022                      location(num_gp,2) = (j+1) * dy
1023                      location(num_gp,3) = k * dz - 0.5_wp * dz
1024                      ei(num_gp)     = e(k,j+1,i+1)
1025                      dissi(num_gp)  = diss(k,j+1,i+1)
1026                      de_dxi(num_gp) = 0.0_wp
1027                      de_dyi(num_gp) = de_dy(k,j+1,i+1)
1028                      de_dzi(num_gp) = de_dz(k,j+1,i+1)
1029                   ENDIF
1030
1031!
1032!--                If wall between gridpoint 1 and gridpoint 2, then
1033!--                Neumann boundary condition has to be applied
1034                   IF ( gp_outside_of_building(1) == 1  .AND. &
1035                        gp_outside_of_building(2) == 0 )  THEN
1036                      num_gp = num_gp + 1
1037                      location(num_gp,1) = i * dx
1038                      location(num_gp,2) = j * dy + 0.5_wp * dy
1039                      location(num_gp,3) = k * dz - 0.5_wp * dz
1040                      ei(num_gp)     = e(k,j,i)
1041                      dissi(num_gp)  = diss(k,j,i)
1042                      de_dxi(num_gp) = de_dx(k,j,i)
1043                      de_dyi(num_gp) = 0.0_wp
1044                      de_dzi(num_gp) = de_dz(k,j,i) 
1045                   ENDIF
1046
1047                   IF ( gp_outside_of_building(2) == 1  .AND. &
1048                        gp_outside_of_building(1) == 0 )  THEN
1049                      num_gp = num_gp + 1
1050                      location(num_gp,1) = i * dx
1051                      location(num_gp,2) = j * dy + 0.5_wp * dy
1052                      location(num_gp,3) = k * dz - 0.5_wp * dz
1053                      ei(num_gp)     = e(k,j+1,i)
1054                      dissi(num_gp)  = diss(k,j+1,i)
1055                      de_dxi(num_gp) = de_dx(k,j+1,i)
1056                      de_dyi(num_gp) = 0.0_wp
1057                      de_dzi(num_gp) = de_dz(k,j+1,i)
1058                   ENDIF
1059
1060!
1061!--                If wall between gridpoint 3 and gridpoint 7, then
1062!--                Neumann boundary condition has to be applied
1063                   IF ( gp_outside_of_building(3) == 1  .AND. &
1064                        gp_outside_of_building(7) == 0 )  THEN
1065                      num_gp = num_gp + 1
1066                      location(num_gp,1) = i * dx + 0.5_wp * dx
1067                      location(num_gp,2) = j * dy
1068                      location(num_gp,3) = k * dz + 0.5_wp * dz
1069                      ei(num_gp)     = e(k+1,j,i)
1070                      dissi(num_gp)  = diss(k+1,j,i)
1071                      de_dxi(num_gp) = 0.0_wp
1072                      de_dyi(num_gp) = de_dy(k+1,j,i)
1073                      de_dzi(num_gp) = de_dz(k+1,j,i) 
1074                   ENDIF
1075
1076                   IF ( gp_outside_of_building(7) == 1  .AND. &
1077                        gp_outside_of_building(3) == 0 )  THEN
1078                      num_gp = num_gp + 1
1079                      location(num_gp,1) = i * dx + 0.5_wp * dx
1080                      location(num_gp,2) = j * dy
1081                      location(num_gp,3) = k * dz + 0.5_wp * dz
1082                      ei(num_gp)     = e(k+1,j,i+1)
1083                      dissi(num_gp)  = diss(k+1,j,i+1)
1084                      de_dxi(num_gp) = 0.0_wp
1085                      de_dyi(num_gp) = de_dy(k+1,j,i+1)
1086                      de_dzi(num_gp) = de_dz(k+1,j,i+1)
1087                   ENDIF
1088
1089!
1090!--                If wall between gridpoint 7 and gridpoint 8, then
1091!--                Neumann boundary condition has to be applied
1092                   IF ( gp_outside_of_building(7) == 1  .AND. &
1093                        gp_outside_of_building(8) == 0 )  THEN
1094                      num_gp = num_gp + 1
1095                      location(num_gp,1) = (i+1) * dx
1096                      location(num_gp,2) = j * dy + 0.5_wp * dy
1097                      location(num_gp,3) = k * dz + 0.5_wp * dz
1098                      ei(num_gp)     = e(k+1,j,i+1)
1099                      dissi(num_gp)  = diss(k+1,j,i+1)
1100                      de_dxi(num_gp) = de_dx(k+1,j,i+1)
1101                      de_dyi(num_gp) = 0.0_wp
1102                      de_dzi(num_gp) = de_dz(k+1,j,i+1)
1103                   ENDIF
1104
1105                   IF ( gp_outside_of_building(8) == 1  .AND. &
1106                        gp_outside_of_building(7) == 0 )  THEN
1107                      num_gp = num_gp + 1
1108                      location(num_gp,1) = (i+1) * dx
1109                      location(num_gp,2) = j * dy + 0.5_wp * dy
1110                      location(num_gp,3) = k * dz + 0.5_wp * dz
1111                      ei(num_gp)     = e(k+1,j+1,i+1)
1112                      dissi(num_gp)  = diss(k+1,j+1,i+1)
1113                      de_dxi(num_gp) = de_dx(k+1,j+1,i+1)
1114                      de_dyi(num_gp) = 0.0_wp
1115                      de_dzi(num_gp) = de_dz(k+1,j+1,i+1)
1116                   ENDIF
1117
1118!
1119!--                If wall between gridpoint 4 and gridpoint 8, then
1120!--                Neumann boundary condition has to be applied
1121                   IF ( gp_outside_of_building(4) == 1  .AND. &
1122                        gp_outside_of_building(8) == 0 )  THEN
1123                      num_gp = num_gp + 1
1124                      location(num_gp,1) = i * dx + 0.5_wp * dx
1125                      location(num_gp,2) = (j+1) * dy
1126                      location(num_gp,3) = k * dz + 0.5_wp * dz
1127                      ei(num_gp)     = e(k+1,j+1,i)
1128                      dissi(num_gp)  = diss(k+1,j+1,i)
1129                      de_dxi(num_gp) = 0.0_wp
1130                      de_dyi(num_gp) = de_dy(k+1,j+1,i)
1131                      de_dzi(num_gp) = de_dz(k+1,j+1,i)
1132                   ENDIF
1133
1134                   IF ( gp_outside_of_building(8) == 1  .AND. &
1135                        gp_outside_of_building(4) == 0 )  THEN
1136                      num_gp = num_gp + 1
1137                      location(num_gp,1) = i * dx + 0.5_wp * dx
1138                      location(num_gp,2) = (j+1) * dy
1139                      location(num_gp,3) = k * dz + 0.5_wp * dz
1140                      ei(num_gp)     = e(k+1,j+1,i+1)
1141                      dissi(num_gp)  = diss(k+1,j+1,i+1)
1142                      de_dxi(num_gp) = 0.0_wp
1143                      de_dyi(num_gp) = de_dy(k+1,j+1,i+1)
1144                      de_dzi(num_gp) = de_dz(k+1,j+1,i+1)
1145                   ENDIF
1146
1147!
1148!--                If wall between gridpoint 3 and gridpoint 4, then
1149!--                Neumann boundary condition has to be applied
1150                   IF ( gp_outside_of_building(3) == 1  .AND. &
1151                        gp_outside_of_building(4) == 0 )  THEN
1152                      num_gp = num_gp + 1
1153                      location(num_gp,1) = i * dx
1154                      location(num_gp,2) = j * dy + 0.5_wp * dy
1155                      location(num_gp,3) = k * dz + 0.5_wp * dz
1156                      ei(num_gp)     = e(k+1,j,i)
1157                      dissi(num_gp)  = diss(k+1,j,i)
1158                      de_dxi(num_gp) = de_dx(k+1,j,i)
1159                      de_dyi(num_gp) = 0.0_wp
1160                      de_dzi(num_gp) = de_dz(k+1,j,i)
1161                   ENDIF
1162
1163                   IF ( gp_outside_of_building(4) == 1  .AND. &
1164                        gp_outside_of_building(3) == 0 )  THEN
1165                      num_gp = num_gp + 1
1166                      location(num_gp,1) = i * dx
1167                      location(num_gp,2) = j * dy + 0.5_wp * dy
1168                      location(num_gp,3) = k * dz + 0.5_wp * dz
1169                      ei(num_gp)     = e(k+1,j+1,i)
1170                      dissi(num_gp)  = diss(k+1,j+1,i)
1171                      de_dxi(num_gp) = de_dx(k+1,j+1,i)
1172                      de_dyi(num_gp) = 0.0_wp
1173                      de_dzi(num_gp) = de_dz(k+1,j+1,i)
1174                   ENDIF
1175
1176!
1177!--                If wall between gridpoint 1 and gridpoint 3, then
1178!--                Neumann boundary condition has to be applied
1179!--                (only one case as only building beneath is possible)
1180                   IF ( gp_outside_of_building(1) == 0  .AND. &
1181                        gp_outside_of_building(3) == 1 )  THEN
1182                      num_gp = num_gp + 1
1183                      location(num_gp,1) = i * dx
1184                      location(num_gp,2) = j * dy
1185                      location(num_gp,3) = k * dz
1186                      ei(num_gp)     = e(k+1,j,i)
1187                      dissi(num_gp)  = diss(k+1,j,i)
1188                      de_dxi(num_gp) = de_dx(k+1,j,i)
1189                      de_dyi(num_gp) = de_dy(k+1,j,i)
1190                      de_dzi(num_gp) = 0.0_wp
1191                   ENDIF
1192
1193!
1194!--                If wall between gridpoint 5 and gridpoint 7, then
1195!--                Neumann boundary condition has to be applied
1196!--                (only one case as only building beneath is possible)
1197                   IF ( gp_outside_of_building(5) == 0  .AND. &
1198                        gp_outside_of_building(7) == 1 )  THEN
1199                      num_gp = num_gp + 1
1200                      location(num_gp,1) = (i+1) * dx
1201                      location(num_gp,2) = j * dy
1202                      location(num_gp,3) = k * dz
1203                      ei(num_gp)     = e(k+1,j,i+1)
1204                      dissi(num_gp)  = diss(k+1,j,i+1)
1205                      de_dxi(num_gp) = de_dx(k+1,j,i+1)
1206                      de_dyi(num_gp) = de_dy(k+1,j,i+1)
1207                      de_dzi(num_gp) = 0.0_wp
1208                   ENDIF
1209
1210!
1211!--                If wall between gridpoint 2 and gridpoint 4, then
1212!--                Neumann boundary condition has to be applied
1213!--                (only one case as only building beneath is possible)
1214                   IF ( gp_outside_of_building(2) == 0  .AND. &
1215                        gp_outside_of_building(4) == 1 )  THEN
1216                      num_gp = num_gp + 1
1217                      location(num_gp,1) = i * dx
1218                      location(num_gp,2) = (j+1) * dy
1219                      location(num_gp,3) = k * dz
1220                      ei(num_gp)     = e(k+1,j+1,i)
1221                      dissi(num_gp)  = diss(k+1,j+1,i)
1222                      de_dxi(num_gp) = de_dx(k+1,j+1,i)
1223                      de_dyi(num_gp) = de_dy(k+1,j+1,i)
1224                      de_dzi(num_gp) = 0.0_wp
1225                   ENDIF
1226
1227!
1228!--                If wall between gridpoint 6 and gridpoint 8, then
1229!--                Neumann boundary condition has to be applied
1230!--                (only one case as only building beneath is possible)
1231                   IF ( gp_outside_of_building(6) == 0  .AND. &
1232                        gp_outside_of_building(8) == 1 )  THEN
1233                      num_gp = num_gp + 1
1234                      location(num_gp,1) = (i+1) * dx
1235                      location(num_gp,2) = (j+1) * dy
1236                      location(num_gp,3) = k * dz
1237                      ei(num_gp)     = e(k+1,j+1,i+1)
1238                      dissi(num_gp)  = diss(k+1,j+1,i+1)
1239                      de_dxi(num_gp) = de_dx(k+1,j+1,i+1)
1240                      de_dyi(num_gp) = de_dy(k+1,j+1,i+1)
1241                      de_dzi(num_gp) = 0.0_wp
1242                   ENDIF
1243     
1244!
1245!--                Carry out the interpolation
1246                   IF ( num_gp == 1 )  THEN
1247!
1248!--                   If only one of the gridpoints is situated outside of the
1249!--                   building, it follows that the values at the particle
1250!--                   location are the same as the gridpoint values
1251                      e_int(n)     = ei(num_gp)   
1252                      diss_int(n)  = dissi(num_gp) 
1253                      de_dx_int(n) = de_dxi(num_gp)
1254                      de_dy_int(n) = de_dyi(num_gp)
1255                      de_dz_int(n) = de_dzi(num_gp)
1256!
1257!--                   Set flag for stochastic equation which disables calculation
1258!--                   of drift and memory term near topography.
1259                      term_1_2(n) = 0.0_wp
1260                   ELSE IF ( num_gp > 1 )  THEN
1261   
1262                      d_sum = 0.0_wp
1263!
1264!--                   Evaluation of the distances between the gridpoints
1265!--                   contributing to the interpolated values, and the particle
1266!--                   location
1267                      DO  agp = 1, num_gp
1268                         d_gp_pl(agp) = ( particles(n)%x-location(agp,1) )**2  &
1269                                      + ( particles(n)%y-location(agp,2) )**2  &
1270                                      + ( zv(n)-location(agp,3) )**2
1271                         d_sum        = d_sum + d_gp_pl(agp)
1272                      ENDDO
1273   
1274!
1275!--                  Finally the interpolation can be carried out
1276                      e_int(n)     = 0.0_wp 
1277                      diss_int(n)  = 0.0_wp 
1278                      de_dx_int(n) = 0.0_wp 
1279                      de_dy_int(n) = 0.0_wp 
1280                      de_dz_int(n) = 0.0_wp 
1281                      DO  agp = 1, num_gp
1282                         e_int(n)     = e_int(n)     + ( d_sum - d_gp_pl(agp) ) * &
1283                                                ei(agp) / ( (num_gp-1) * d_sum )
1284                         diss_int(n)  = diss_int(n)  + ( d_sum - d_gp_pl(agp) ) * &
1285                                             dissi(agp) / ( (num_gp-1) * d_sum )
1286                         de_dx_int(n) = de_dx_int(n) + ( d_sum - d_gp_pl(agp) ) * &
1287                                            de_dxi(agp) / ( (num_gp-1) * d_sum )
1288                         de_dy_int(n) = de_dy_int(n) + ( d_sum - d_gp_pl(agp) ) * &
1289                                            de_dyi(agp) / ( (num_gp-1) * d_sum )
1290                         de_dz_int(n) = de_dz_int(n) + ( d_sum - d_gp_pl(agp) ) * &
1291                                            de_dzi(agp) / ( (num_gp-1) * d_sum )
1292                      ENDDO
1293   
1294                   ENDIF
1295                   e_int(n)     = MAX( 1E-20_wp, e_int(n)     )
1296                   diss_int(n)  = MAX( 1E-20_wp, diss_int(n)  )
1297                   de_dx_int(n) = MAX( 1E-20_wp, de_dx_int(n) )
1298                   de_dy_int(n) = MAX( 1E-20_wp, de_dy_int(n) ) 
1299                   de_dz_int(n) = MAX( 1E-20_wp, de_dz_int(n) ) 
1300!
1301!--                Set flag for stochastic equation which disables calculation
1302!--                of drift and memory term near topography.
1303                   term_1_2(n) = 0.0_wp
1304                ENDIF
1305             ENDDO
1306          ENDDO
1307       ENDIF
1308
1309       DO nb = 0,7
1310          i = ip + block_offset(nb)%i_off
1311          j = jp + block_offset(nb)%j_off
1312          k = kp + block_offset(nb)%k_off
1313
1314          DO  n = start_index(nb), end_index(nb)
1315!
1316!--          Vertical interpolation of the horizontally averaged SGS TKE and
1317!--          resolved-scale velocity variances and use the interpolated values
1318!--          to calculate the coefficient fs, which is a measure of the ratio
1319!--          of the subgrid-scale turbulent kinetic energy to the total amount
1320!--          of turbulent kinetic energy.
1321             IF ( k == 0 )  THEN
1322                e_mean_int = hom(0,1,8,0)
1323             ELSE
1324                e_mean_int = hom(k,1,8,0) +                                    &
1325                                           ( hom(k+1,1,8,0) - hom(k,1,8,0) ) / &
1326                                           ( zu(k+1) - zu(k) ) *               &
1327                                           ( zv(n) - zu(k) )
1328             ENDIF
1329
1330             kw = kp - 1
1331
1332             IF ( k == 0 )  THEN
1333                aa  = hom(k+1,1,30,0)  * ( zv(n) / &
1334                                         ( 0.5_wp * ( zu(k+1) - zu(k) ) ) )
1335                bb  = hom(k+1,1,31,0)  * ( zv(n) / &
1336                                         ( 0.5_wp * ( zu(k+1) - zu(k) ) ) )
1337                cc  = hom(kw+1,1,32,0) * ( zv(n) / &
1338                                         ( 1.0_wp * ( zw(kw+1) - zw(kw) ) ) )
1339             ELSE
1340                aa  = hom(k,1,30,0) + ( hom(k+1,1,30,0) - hom(k,1,30,0) ) *    &
1341                           ( ( zv(n) - zu(k) ) / ( zu(k+1) - zu(k) ) )
1342                bb  = hom(k,1,31,0) + ( hom(k+1,1,31,0) - hom(k,1,31,0) ) *    &
1343                           ( ( zv(n) - zu(k) ) / ( zu(k+1) - zu(k) ) )
1344                cc  = hom(kw,1,32,0) + ( hom(kw+1,1,32,0)-hom(kw,1,32,0) ) *   &
1345                           ( ( zv(n) - zw(kw) ) / ( zw(kw+1)-zw(kw) ) )
1346             ENDIF
1347
1348             vv_int = ( 1.0_wp / 3.0_wp ) * ( aa + bb + cc )
1349!
1350!--          Needed to avoid NaN particle velocities. The value of 1.0 is just
1351!--          an educated guess for the given case.
1352             IF ( vv_int + ( 2.0_wp / 3.0_wp ) * e_mean_int == 0.0_wp )  THEN
1353                fs_int(n) = 1.0_wp
1354             ELSE
1355                fs_int(n) = ( 2.0_wp / 3.0_wp ) * e_mean_int /                 &
1356                            ( vv_int + ( 2.0_wp / 3.0_wp ) * e_mean_int )
1357             ENDIF
1358
1359          ENDDO
1360       ENDDO
1361
1362       DO  nb = 0, 7
1363          DO  n = start_index(nb), end_index(nb)
1364             rg(n,1) = random_gauss( iran_part, 5.0_wp )
1365             rg(n,2) = random_gauss( iran_part, 5.0_wp )
1366             rg(n,3) = random_gauss( iran_part, 5.0_wp )
1367          ENDDO
1368       ENDDO
1369
1370       DO  nb = 0, 7
1371          DO  n = start_index(nb), end_index(nb)
1372
1373!
1374!--          Calculate the Lagrangian timescale according to Weil et al. (2004).
1375             lagr_timescale = ( 4.0_wp * e_int(n) + 1E-20_wp ) / &
1376                              ( 3.0_wp * fs_int(n) * c_0 * diss_int(n) + 1E-20_wp )
1377
1378!
1379!--          Calculate the next particle timestep. dt_gap is the time needed to
1380!--          complete the current LES timestep.
1381             dt_gap = dt_3d - particles(n)%dt_sum
1382             dt_particle(n) = MIN( dt_3d, 0.025_wp * lagr_timescale, dt_gap )
1383
1384!
1385!--          The particle timestep should not be too small in order to prevent
1386!--          the number of particle timesteps of getting too large
1387             IF ( dt_particle(n) < dt_min_part  .AND.  dt_min_part < dt_gap )  THEN
1388                dt_particle(n) = dt_min_part
1389             ENDIF
1390
1391!
1392!--          Calculate the SGS velocity components
1393             IF ( particles(n)%age == 0.0_wp )  THEN
1394!
1395!--             For new particles the SGS components are derived from the SGS
1396!--             TKE. Limit the Gaussian random number to the interval
1397!--             [-5.0*sigma, 5.0*sigma] in order to prevent the SGS velocities
1398!--             from becoming unrealistically large.
1399                particles(n)%rvar1 = SQRT( 2.0_wp * sgs_wf_part * e_int(n)     &
1400                                          + 1E-20_wp ) *                       &
1401                                     ( rg(n,1) - 1.0_wp )
1402                particles(n)%rvar2 = SQRT( 2.0_wp * sgs_wf_part * e_int(n)     &
1403                                          + 1E-20_wp ) *                       &
1404                                     ( rg(n,2) - 1.0_wp )
1405                particles(n)%rvar3 = SQRT( 2.0_wp * sgs_wf_part * e_int(n)     &
1406                                          + 1E-20_wp ) *                       &
1407                                     ( rg(n,3) - 1.0_wp )
1408
1409             ELSE
1410!
1411!--             Restriction of the size of the new timestep: compared to the
1412!--             previous timestep the increase must not exceed 200%. First,
1413!--             check if age > age_m, in order to prevent that particles get zero
1414!--             timestep.
1415                dt_particle_m = MERGE( dt_particle(n),                         &
1416                                       particles(n)%age - particles(n)%age_m,  &
1417                                       particles(n)%age - particles(n)%age_m < &
1418                                       1E-8_wp )
1419                IF ( dt_particle(n) > 2.0_wp * dt_particle_m )  THEN
1420                   dt_particle(n) = 2.0_wp * dt_particle_m
1421                ENDIF
1422
1423!
1424!--             For old particles the SGS components are correlated with the
1425!--             values from the previous timestep. Random numbers have also to
1426!--             be limited (see above).
1427!--             As negative values for the subgrid TKE are not allowed, the
1428!--             change of the subgrid TKE with time cannot be smaller than
1429!--             -e_int(n)/dt_particle. This value is used as a lower boundary
1430!--             value for the change of TKE
1431                de_dt_min = - e_int(n) / dt_particle(n)
1432
1433                de_dt = ( e_int(n) - particles(n)%e_m ) / dt_particle_m
1434
1435                IF ( de_dt < de_dt_min )  THEN
1436                   de_dt = de_dt_min
1437                ENDIF
1438
1439                CALL weil_stochastic_eq(particles(n)%rvar1, fs_int(n), e_int(n),& 
1440                                        de_dx_int(n), de_dt, diss_int(n),       &
1441                                        dt_particle(n), rg(n,1), term_1_2(n) )
1442
1443                CALL weil_stochastic_eq(particles(n)%rvar2, fs_int(n), e_int(n),& 
1444                                        de_dy_int(n), de_dt, diss_int(n),       &
1445                                        dt_particle(n), rg(n,2), term_1_2(n) )
1446
1447                CALL weil_stochastic_eq(particles(n)%rvar3, fs_int(n), e_int(n),& 
1448                                        de_dz_int(n), de_dt, diss_int(n),       &
1449                                        dt_particle(n), rg(n,3), term_1_2(n) )
1450
1451             ENDIF
1452
1453             u_int(n) = u_int(n) + particles(n)%rvar1
1454             v_int(n) = v_int(n) + particles(n)%rvar2
1455             w_int(n) = w_int(n) + particles(n)%rvar3
1456!
1457!--          Store the SGS TKE of the current timelevel which is needed for
1458!--          for calculating the SGS particle velocities at the next timestep
1459             particles(n)%e_m = e_int(n)
1460          ENDDO
1461       ENDDO
1462
1463    ELSE
1464!
1465!--    If no SGS velocities are used, only the particle timestep has to
1466!--    be set
1467       dt_particle = dt_3d
1468
1469    ENDIF
1470
1471    dens_ratio = particle_groups(particles(1:number_of_particles)%group)%density_ratio
1472
1473    IF ( ANY( dens_ratio == 0.0_wp ) )  THEN
1474       DO  nb = 0, 7
1475          DO  n = start_index(nb), end_index(nb)
1476
1477!
1478!--          Particle advection
1479             IF ( dens_ratio(n) == 0.0_wp )  THEN
1480!
1481!--             Pure passive transport (without particle inertia)
1482                particles(n)%x = xv(n) + u_int(n) * dt_particle(n)
1483                particles(n)%y = yv(n) + v_int(n) * dt_particle(n)
1484                particles(n)%z = zv(n) + w_int(n) * dt_particle(n)
1485
1486                particles(n)%speed_x = u_int(n)
1487                particles(n)%speed_y = v_int(n)
1488                particles(n)%speed_z = w_int(n)
1489
1490             ELSE
1491!
1492!--             Transport of particles with inertia
1493                particles(n)%x = particles(n)%x + particles(n)%speed_x * &
1494                                                  dt_particle(n)
1495                particles(n)%y = particles(n)%y + particles(n)%speed_y * &
1496                                                  dt_particle(n)
1497                particles(n)%z = particles(n)%z + particles(n)%speed_z * &
1498                                                  dt_particle(n)
1499
1500!
1501!--             Update of the particle velocity
1502                IF ( cloud_droplets )  THEN
1503!
1504!--                Terminal velocity is computed for vertical direction (Rogers et
1505!--                al., 1993, J. Appl. Meteorol.)
1506                   diameter = particles(n)%radius * 2000.0_wp !diameter in mm
1507                   IF ( diameter <= d0_rog )  THEN
1508                      w_s = k_cap_rog * diameter * ( 1.0_wp - EXP( -k_low_rog * diameter ) )
1509                   ELSE
1510                      w_s = a_rog - b_rog * EXP( -c_rog * diameter )
1511                   ENDIF
1512
1513!
1514!--                If selected, add random velocities following Soelch and Kaercher
1515!--                (2010, Q. J. R. Meteorol. Soc.)
1516                   IF ( use_sgs_for_particles )  THEN
1517                      lagr_timescale = km(kp,jp,ip) / MAX( e(kp,jp,ip), 1.0E-20_wp )
1518                      RL             = EXP( -1.0_wp * dt_3d / lagr_timescale )
1519                      sigma          = SQRT( e(kp,jp,ip) )
1520
1521                      rg1 = random_gauss( iran_part, 5.0_wp ) - 1.0_wp
1522                      rg2 = random_gauss( iran_part, 5.0_wp ) - 1.0_wp
1523                      rg3 = random_gauss( iran_part, 5.0_wp ) - 1.0_wp
1524
1525                      particles(n)%rvar1 = RL * particles(n)%rvar1 +              &
1526                                           SQRT( 1.0_wp - RL**2 ) * sigma * rg1
1527                      particles(n)%rvar2 = RL * particles(n)%rvar2 +              &
1528                                           SQRT( 1.0_wp - RL**2 ) * sigma * rg2
1529                      particles(n)%rvar3 = RL * particles(n)%rvar3 +              &
1530                                           SQRT( 1.0_wp - RL**2 ) * sigma * rg3
1531
1532                      particles(n)%speed_x = u_int(n) + particles(n)%rvar1
1533                      particles(n)%speed_y = v_int(n) + particles(n)%rvar2
1534                      particles(n)%speed_z = w_int(n) + particles(n)%rvar3 - w_s
1535                   ELSE
1536                      particles(n)%speed_x = u_int(n)
1537                      particles(n)%speed_y = v_int(n)
1538                      particles(n)%speed_z = w_int(n) - w_s
1539                   ENDIF
1540
1541                ELSE
1542
1543                   IF ( use_sgs_for_particles )  THEN
1544                      exp_arg  = particle_groups(particles(n)%group)%exp_arg
1545                      exp_term = EXP( -exp_arg * dt_particle(n) )
1546                   ELSE
1547                      exp_arg  = particle_groups(particles(n)%group)%exp_arg
1548                      exp_term = particle_groups(particles(n)%group)%exp_term
1549                   ENDIF
1550                   particles(n)%speed_x = particles(n)%speed_x * exp_term +         &
1551                                          u_int(n) * ( 1.0_wp - exp_term )
1552                   particles(n)%speed_y = particles(n)%speed_y * exp_term +         &
1553                                          v_int(n) * ( 1.0_wp - exp_term )
1554                   particles(n)%speed_z = particles(n)%speed_z * exp_term +         &
1555                                          ( w_int(n) - ( 1.0_wp - dens_ratio(n) ) * &
1556                                          g / exp_arg ) * ( 1.0_wp - exp_term )
1557                ENDIF
1558
1559             ENDIF
1560          ENDDO
1561       ENDDO
1562   
1563    ELSE
1564
1565       DO  nb = 0, 7
1566          DO  n = start_index(nb), end_index(nb)
1567!
1568!--          Transport of particles with inertia
1569             particles(n)%x = xv(n) + particles(n)%speed_x * dt_particle(n)
1570             particles(n)%y = yv(n) + particles(n)%speed_y * dt_particle(n)
1571             particles(n)%z = zv(n) + particles(n)%speed_z * dt_particle(n)
1572!
1573!--          Update of the particle velocity
1574             IF ( cloud_droplets )  THEN
1575!
1576!--             Terminal velocity is computed for vertical direction (Rogers et al.,
1577!--             1993, J. Appl. Meteorol.)
1578                diameter = particles(n)%radius * 2000.0_wp !diameter in mm
1579                IF ( diameter <= d0_rog )  THEN
1580                   w_s = k_cap_rog * diameter * ( 1.0_wp - EXP( -k_low_rog * diameter ) )
1581                ELSE
1582                   w_s = a_rog - b_rog * EXP( -c_rog * diameter )
1583                ENDIF
1584
1585!
1586!--             If selected, add random velocities following Soelch and Kaercher
1587!--             (2010, Q. J. R. Meteorol. Soc.)
1588                IF ( use_sgs_for_particles )  THEN
1589                    lagr_timescale = km(kp,jp,ip) / MAX( e(kp,jp,ip), 1.0E-20_wp )
1590                    RL             = EXP( -1.0_wp * dt_3d / lagr_timescale )
1591                    sigma          = SQRT( e(kp,jp,ip) )
1592
1593                    rg1 = random_gauss( iran_part, 5.0_wp ) - 1.0_wp
1594                    rg2 = random_gauss( iran_part, 5.0_wp ) - 1.0_wp
1595                    rg3 = random_gauss( iran_part, 5.0_wp ) - 1.0_wp
1596
1597                    particles(n)%rvar1 = RL * particles(n)%rvar1 +                &
1598                                         SQRT( 1.0_wp - RL**2 ) * sigma * rg1
1599                    particles(n)%rvar2 = RL * particles(n)%rvar2 +                &
1600                                         SQRT( 1.0_wp - RL**2 ) * sigma * rg2
1601                    particles(n)%rvar3 = RL * particles(n)%rvar3 +                &
1602                                         SQRT( 1.0_wp - RL**2 ) * sigma * rg3
1603
1604                    particles(n)%speed_x = u_int(n) + particles(n)%rvar1
1605                    particles(n)%speed_y = v_int(n) + particles(n)%rvar2
1606                    particles(n)%speed_z = w_int(n) + particles(n)%rvar3 - w_s
1607                ELSE
1608                    particles(n)%speed_x = u_int(n)
1609                    particles(n)%speed_y = v_int(n)
1610                    particles(n)%speed_z = w_int(n) - w_s
1611                ENDIF
1612
1613             ELSE
1614
1615                IF ( use_sgs_for_particles )  THEN
1616                   exp_arg  = particle_groups(particles(n)%group)%exp_arg
1617                   exp_term = EXP( -exp_arg * dt_particle(n) )
1618                ELSE
1619                   exp_arg  = particle_groups(particles(n)%group)%exp_arg
1620                   exp_term = particle_groups(particles(n)%group)%exp_term
1621                ENDIF
1622                particles(n)%speed_x = particles(n)%speed_x * exp_term +             &
1623                                       u_int(n) * ( 1.0_wp - exp_term )
1624                particles(n)%speed_y = particles(n)%speed_y * exp_term +             &
1625                                       v_int(n) * ( 1.0_wp - exp_term )
1626                particles(n)%speed_z = particles(n)%speed_z * exp_term +             &
1627                                       ( w_int(n) - ( 1.0_wp - dens_ratio(n) ) * g / &
1628                                       exp_arg ) * ( 1.0_wp - exp_term )
1629             ENDIF
1630          ENDDO
1631       ENDDO
1632
1633    ENDIF
1634
1635!
1636!-- Store the old age of the particle ( needed to prevent that a
1637!-- particle crosses several PEs during one timestep, and for the
1638!-- evaluation of the subgrid particle velocity fluctuations )
1639    particles(1:number_of_particles)%age_m = particles(1:number_of_particles)%age
1640
1641    DO  nb = 0, 7
1642       DO  n = start_index(nb), end_index(nb)
1643!
1644!--       Increment the particle age and the total time that the particle
1645!--       has advanced within the particle timestep procedure
1646          particles(n)%age    = particles(n)%age    + dt_particle(n)
1647          particles(n)%dt_sum = particles(n)%dt_sum + dt_particle(n)
1648
1649!
1650!--       Check whether there is still a particle that has not yet completed
1651!--       the total LES timestep
1652          IF ( ( dt_3d - particles(n)%dt_sum ) > 1E-8_wp )  THEN
1653             dt_3d_reached_l = .FALSE.
1654          ENDIF
1655
1656       ENDDO
1657    ENDDO
1658
1659    CALL cpu_log( log_point_s(44), 'lpm_advec', 'pause' )
1660
1661
1662 END SUBROUTINE lpm_advec
1663
1664! Description:
1665! ------------
1666!> Calculation of subgrid-scale particle speed using the stochastic model
1667!> of Weil et al. (2004, JAS, 61, 2877-2887).
1668!------------------------------------------------------------------------------!
1669 SUBROUTINE weil_stochastic_eq( v_sgs, fs_n, e_n, dedxi_n, dedt_n, diss_n,     &
1670                                dt_n, rg_n, fac )
1671
1672    USE kinds
1673
1674    USE particle_attributes,                                                   &
1675        ONLY:  c_0, sgs_wf_part
1676
1677    IMPLICIT NONE
1678
1679    REAL(wp) ::  a1      !< dummy argument
1680    REAL(wp) ::  dedt_n  !< time derivative of TKE at particle position
1681    REAL(wp) ::  dedxi_n !< horizontal derivative of TKE at particle position
1682    REAL(wp) ::  diss_n  !< dissipation at particle position
1683    REAL(wp) ::  dt_n    !< particle timestep
1684    REAL(wp) ::  e_n     !< TKE at particle position
1685    REAL(wp) ::  fac     !< flag to identify adjacent topography
1686    REAL(wp) ::  fs_n    !< weighting factor to prevent that subgrid-scale particle speed becomes too large
1687    REAL(wp) ::  sgs_w   !< constant (1/3)
1688    REAL(wp) ::  rg_n    !< random number
1689    REAL(wp) ::  term1   !< memory term
1690    REAL(wp) ::  term2   !< drift correction term
1691    REAL(wp) ::  term3   !< random term
1692    REAL(wp) ::  v_sgs   !< subgrid-scale velocity component
1693
1694!-- At first, limit TKE to a small non-zero number, in order to prevent
1695!-- the occurrence of extremely large SGS-velocities in case TKE is zero,
1696!-- (could occur at the simulation begin).
1697    e_n = MAX( e_n, 1E-20_wp )
1698!
1699!-- Please note, terms 1 and 2 (drift and memory term, respectively) are
1700!-- multiplied by a flag to switch of both terms near topography.
1701!-- This is necessary, as both terms may cause a subgrid-scale velocity build up
1702!-- if particles are trapped in regions with very small TKE, e.g. in narrow street
1703!-- canyons resolved by only a few grid points. Hence, term 1 and term 2 are
1704!-- disabled if one of the adjacent grid points belongs to topography.
1705!-- Moreover, in this case, the  previous subgrid-scale component is also set
1706!-- to zero.
1707
1708    a1 = fs_n * c_0 * diss_n
1709!
1710!-- Memory term
1711    term1 = - a1 * v_sgs * dt_n / ( 4.0_wp * sgs_wf_part * e_n + 1E-20_wp )    &
1712                 * fac
1713!
1714!-- Drift correction term
1715    term2 = ( ( dedt_n * v_sgs / e_n ) + dedxi_n ) * 0.5_wp * dt_n              &
1716                 * fac
1717!
1718!-- Random term
1719    term3 = SQRT( MAX( a1, 1E-20 ) ) * ( rg_n - 1.0_wp ) * SQRT( dt_n )
1720!
1721!-- In cese one of the adjacent grid-boxes belongs to topograhy, the previous
1722!-- subgrid-scale velocity component is set to zero, in order to prevent a
1723!-- velocity build-up.
1724!-- This case, set also previous subgrid-scale component to zero.
1725    v_sgs = v_sgs * fac + term1 + term2 + term3
1726
1727 END SUBROUTINE weil_stochastic_eq
Note: See TracBrowser for help on using the repository browser.