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

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