source: palm/trunk/SOURCE/advec_particles.f90 @ 268

Last change on this file since 268 was 264, checked in by raasch, 16 years ago

new dvrp features added

  • Property svn:keywords set to Id
File size: 165.4 KB
Line 
1 SUBROUTINE advec_particles
2
3!------------------------------------------------------------------------------!
4! Current revisions:
5! -----------------
6! Particle attributes are set with new routine set_particle_attributes.
7! Output of NetCDF messages with aid of message handling routine.
8! Output of messages replaced by message handling routine
9! Bugfix: error in check, if particles moved further than one subdomain length.
10!         This check must not be applied for newly released particles
11! Bugfix: several tail counters are initialized, particle_tail_coordinates is
12! only written to file if its third index is > 0
13! TEST: PRINT statements on unit 9 (commented out)
14!
15! Former revisions:
16! -----------------
17! $Id: advec_particles.f90 264 2009-03-21 08:14:44Z letzel $
18!
19! 212 2008-11-11 09:09:24Z raasch
20! Bugfix in calculating k index in case of oceans runs (sort_particles)
21!
22! 150 2008-02-29 08:19:58Z raasch
23! Bottom boundary condition and vertical index calculations adjusted for
24! ocean runs.
25!
26! 119 2007-10-17 10:27:13Z raasch
27! Sorting of particles is controlled by dt_sort_particles and moved from
28! the SGS timestep loop after the end of this loop.
29! Bugfix: pleft/pright changed to pnorth/psouth in sendrecv of particle tail
30! numbers along y
31! Small bugfixes in the SGS part
32!
33! 106 2007-08-16 14:30:26Z raasch
34! remaining variables iran changed to iran_part
35!
36! 95 2007-06-02 16:48:38Z raasch
37! hydro_press renamed hyp
38!
39! 75 2007-03-22 09:54:05Z raasch
40! Particle reflection at vertical walls implemented in new subroutine
41! particle_boundary_conds,
42! vertical walls are regarded in the SGS model,
43! + user_advec_particles, particles-package is now part of the defaut code,
44! array arguments in sendrecv calls have to refer to first element (1) due to
45! mpich (mpiI) interface requirements,
46! 2nd+3rd argument removed from exchange horiz
47!
48! 16 2007-02-15 13:16:47Z raasch
49! Bugfix: wrong if-clause from revision 1.32
50!
51! r4 | raasch | 2007-02-13 12:33:16 +0100 (Tue, 13 Feb 2007)
52! RCS Log replace by Id keyword, revision history cleaned up
53!
54! Revision 1.32  2007/02/11 12:48:20  raasch
55! Allways the lower level k is used for interpolation
56! Bugfix: new particles are released only if end_time_prel > simulated_time
57! Bugfix: transfer of particles when x < -0.5*dx (0.0 before), etc.,
58!         index i,j used instead of cartesian (x,y) coordinate to check for
59!         transfer because this failed under very rare conditions
60! Bugfix: calculation of number of particles with same radius as the current
61!         particle (cloud droplet code)
62!
63! Revision 1.31  2006/08/17 09:21:01  raasch
64! Two more compilation errors removed from the last revision
65!
66! Revision 1.30  2006/08/17 09:11:17  raasch
67! Two compilation errors removed from the last revision
68!
69! Revision 1.29  2006/08/04 14:05:01  raasch
70! Subgrid scale velocities are (optionally) included for calculating the
71! particle advection, new counters trlp_count_sum, etc. for accumulating
72! the number of particles exchanged between the subdomains during all
73! sub-timesteps (if sgs velocities are included), +3d-arrays de_dx/y/z,
74! izuf renamed iran, output of particle time series
75!
76! Revision 1.1  1999/11/25 16:16:06  raasch
77! Initial revision
78!
79!
80! Description:
81! ------------
82! Particle advection
83!------------------------------------------------------------------------------!
84
85    USE arrays_3d
86    USE cloud_parameters
87    USE constants
88    USE control_parameters
89    USE cpulog
90    USE grid_variables
91    USE indices
92    USE interfaces
93    USE netcdf_control
94    USE particle_attributes
95    USE pegrid
96    USE random_function_mod
97    USE statistics
98
99    IMPLICIT NONE
100
101    INTEGER ::  agp, deleted_particles, deleted_tails, i, ie, ii, inc, is, j,  &
102                jj, js, k, kk, kw, m, n, nc, nn, num_gp, psi, tlength,         &
103                trlp_count, trlp_count_sum, trlp_count_recv,                   &
104                trlp_count_recv_sum, trlpt_count, trlpt_count_recv,            &
105                trnp_count, trnp_count_sum, trnp_count_recv,                   &
106                trnp_count_recv_sum, trnpt_count, trnpt_count_recv,            &
107                trrp_count, trrp_count_sum, trrp_count_recv,                   &
108                trrp_count_recv_sum, trrpt_count, trrpt_count_recv,            &
109                trsp_count, trsp_count_sum, trsp_count_recv,                   &
110                trsp_count_recv_sum, trspt_count, trspt_count_recv, nd
111
112    INTEGER ::  gp_outside_of_building(1:8)
113
114    LOGICAL ::  dt_3d_reached, dt_3d_reached_l, prt_position
115
116    REAL    ::  aa, arg, bb, cc, dd, delta_r, dens_ratio, de_dt, de_dt_min,    &
117                de_dx_int, de_dx_int_l, de_dx_int_u, de_dy_int, de_dy_int_l,   &
118                de_dy_int_u, de_dz_int, de_dz_int_l, de_dz_int_u, diss_int,    &
119                diss_int_l, diss_int_u, distance, dt_gap, dt_particle,         &
120                dt_particle_m, d_radius, d_sum, e_a, e_int, e_int_l, e_int_u,  &
121                e_mean_int, e_s, exp_arg, exp_term, fs_int, gg,                &
122                lagr_timescale, mean_r, new_r, p_int, pt_int, pt_int_l,        &
123                pt_int_u, q_int, q_int_l, q_int_u, ql_int, ql_int_l, ql_int_u, &
124                random_gauss, sl_r3, sl_r4, s_r3, s_r4, t_int, u_int, u_int_l, &
125                u_int_u, vv_int, v_int, v_int_l, v_int_u, w_int, w_int_l,      &
126                w_int_u, x, y
127
128    REAL, DIMENSION(1:30) ::  de_dxi, de_dyi, de_dzi, dissi, d_gp_pl, ei
129
130    REAL    ::  location(1:30,1:3)
131
132    REAL, DIMENSION(nzb:nzt+1,nys-1:nyn+1,nxl-1:nxr+1) ::  de_dx, de_dy, de_dz
133
134    REAL, DIMENSION(:,:,:), ALLOCATABLE ::  trlpt, trnpt, trrpt, trspt
135
136    TYPE(particle_type) ::  tmp_particle
137
138    TYPE(particle_type), DIMENSION(:), ALLOCATABLE ::  trlp, trnp, trrp, trsp
139
140
141    CALL cpu_log( log_point(25), 'advec_particles', 'start' )
142
143!    IF ( number_of_particles /= number_of_tails )  THEN
144!       WRITE (9,*) '--- advec_particles: #1'
145!       WRITE (9,*) '    #of p=',number_of_particles,' #of t=',number_of_tails
146!       CALL local_flush( 9 )
147!    ENDIF
148!
149!-- Write particle data on file for later analysis.
150!-- This has to be done here (before particles are advected) in order
151!-- to allow correct output in case of dt_write_particle_data = dt_prel =
152!-- particle_maximum_age. Otherwise (if output is done at the end of this
153!-- subroutine), the relevant particles would have been already deleted.
154!-- The MOD function allows for changes in the output interval with restart
155!-- runs.
156!-- Attention: change version number for unit 85 (in routine check_open)
157!--            whenever the output format for this unit is changed!
158    time_write_particle_data = time_write_particle_data + dt_3d
159    IF ( time_write_particle_data >= dt_write_particle_data )  THEN
160
161       CALL cpu_log( log_point_s(40), 'advec_part_io', 'start' )
162       CALL check_open( 85 )
163       WRITE ( 85 )  simulated_time, maximum_number_of_particles, &
164                     number_of_particles
165       WRITE ( 85 )  particles
166       WRITE ( 85 )  maximum_number_of_tailpoints, maximum_number_of_tails, &
167                     number_of_tails
168       IF ( maximum_number_of_tails > 0 )  THEN
169          WRITE ( 85 )  particle_tail_coordinates
170       ENDIF
171       CALL close_file( 85 )
172
173       IF ( netcdf_output )  CALL output_particles_netcdf
174
175       time_write_particle_data = MOD( time_write_particle_data, &
176                                  MAX( dt_write_particle_data, dt_3d ) )
177       CALL cpu_log( log_point_s(40), 'advec_part_io', 'stop' )
178    ENDIF
179
180!
181!-- Calculate exponential term used in case of particle inertia for each
182!-- of the particle groups
183    CALL cpu_log( log_point_s(41), 'advec_part_exp', 'start' )
184    DO  m = 1, number_of_particle_groups
185       IF ( particle_groups(m)%density_ratio /= 0.0 )  THEN
186          particle_groups(m)%exp_arg  =                                        &
187                    4.5 * particle_groups(m)%density_ratio *                   &
188                    molecular_viscosity / ( particle_groups(m)%radius )**2
189          particle_groups(m)%exp_term = EXP( -particle_groups(m)%exp_arg * &
190                                             dt_3d )
191       ENDIF
192    ENDDO
193    CALL cpu_log( log_point_s(41), 'advec_part_exp', 'stop' )
194
195!    WRITE ( 9, * ) '*** advec_particles: ##0.3'
196!    CALL local_flush( 9 )
197!    nd = 0
198!    DO  n = 1, number_of_particles
199!       IF ( .NOT. particle_mask(n) )  nd = nd + 1
200!    ENDDO
201!    IF ( nd /= deleted_particles ) THEN
202!       WRITE (9,*) '*** nd=',nd,' deleted_particles=',deleted_particles
203!       CALL local_flush( 9 )
204!       CALL MPI_ABORT( comm2d, 9999, ierr )
205!    ENDIF
206
207!
208!-- Particle (droplet) growth by condensation/evaporation and collision
209    IF ( cloud_droplets )  THEN
210
211!
212!--    Reset summation arrays
213       ql_c = 0.0;  ql_v = 0.0;  ql_vp = 0.0
214
215!
216!--    Particle growth by condensation/evaporation
217       CALL cpu_log( log_point_s(42), 'advec_part_cond', 'start' )
218       DO  n = 1, number_of_particles
219!
220!--       Interpolate temperature and humidity.
221!--       First determine left, south, and bottom index of the arrays.
222          i = particles(n)%x * ddx
223          j = particles(n)%y * ddy
224          k = ( particles(n)%z + 0.5 * dz * atmos_ocean_sign ) / dz  &
225              + offset_ocean_nzt                     ! only exact if equidistant
226
227          x  = particles(n)%x - i * dx
228          y  = particles(n)%y - j * dy
229          aa = x**2          + y**2
230          bb = ( dx - x )**2 + y**2
231          cc = x**2          + ( dy - y )**2
232          dd = ( dx - x )**2 + ( dy - y )**2
233          gg = aa + bb + cc + dd
234
235          pt_int_l = ( ( gg - aa ) * pt(k,j,i)   + ( gg - bb ) * pt(k,j,i+1)   &
236                     + ( gg - cc ) * pt(k,j+1,i) + ( gg - dd ) * pt(k,j+1,i+1) &
237                     ) / ( 3.0 * gg )
238
239          pt_int_u = ( ( gg-aa ) * pt(k+1,j,i)   + ( gg-bb ) * pt(k+1,j,i+1)   &
240                     + ( gg-cc ) * pt(k+1,j+1,i) + ( gg-dd ) * pt(k+1,j+1,i+1) &
241                     ) / ( 3.0 * gg )
242
243          pt_int = pt_int_l + ( particles(n)%z - zu(k) ) / dz * &
244                              ( pt_int_u - pt_int_l )
245
246          q_int_l = ( ( gg - aa ) * q(k,j,i)   + ( gg - bb ) * q(k,j,i+1)   &
247                    + ( gg - cc ) * q(k,j+1,i) + ( gg - dd ) * q(k,j+1,i+1) &
248                    ) / ( 3.0 * gg )
249
250          q_int_u = ( ( gg-aa ) * q(k+1,j,i)   + ( gg-bb ) * q(k+1,j,i+1)   &
251                    + ( gg-cc ) * q(k+1,j+1,i) + ( gg-dd ) * q(k+1,j+1,i+1) &
252                    ) / ( 3.0 * gg )
253
254          q_int = q_int_l + ( particles(n)%z - zu(k) ) / dz * &
255                              ( q_int_u - q_int_l )
256
257          ql_int_l = ( ( gg - aa ) * ql(k,j,i)   + ( gg - bb ) * ql(k,j,i+1)   &
258                     + ( gg - cc ) * ql(k,j+1,i) + ( gg - dd ) * ql(k,j+1,i+1) &
259                     ) / ( 3.0 * gg )
260
261          ql_int_u = ( ( gg-aa ) * ql(k+1,j,i)   + ( gg-bb ) * ql(k+1,j,i+1)   &
262                     + ( gg-cc ) * ql(k+1,j+1,i) + ( gg-dd ) * ql(k+1,j+1,i+1) &
263                     ) / ( 3.0 * gg )
264
265          ql_int = ql_int_l + ( particles(n)%z - zu(k) ) / dz * &
266                                ( ql_int_u - ql_int_l )
267
268!
269!--       Calculate real temperature and saturation vapor pressure
270          p_int = hyp(k) + ( particles(n)%z - zu(k) ) / dz * ( hyp(k+1)-hyp(k) )
271          t_int = pt_int * ( p_int / 100000.0 )**0.286
272
273          e_s = 611.0 * EXP( l_d_rv * ( 3.6609E-3 - 1.0 / t_int ) )
274
275!
276!--       Current vapor pressure
277          e_a = q_int * p_int / ( 0.378 * q_int + 0.622 )
278
279!
280!--       Change in radius by condensation/evaporation
281!--       ATTENTION: this is only an approximation for large radii
282          arg = particles(n)%radius**2 + 2.0 * dt_3d *                     &
283                        ( e_a / e_s - 1.0 ) /                              &
284                        ( ( l_d_rv / t_int - 1.0 ) * l_v * rho_l / t_int / &
285                          thermal_conductivity_l +                         &
286                          rho_l * r_v * t_int / diff_coeff_l / e_s )
287          IF ( arg < 1.0E-14 )  THEN
288             new_r = 1.0E-7
289          ELSE
290             new_r = SQRT( arg )
291          ENDIF
292
293          delta_r = new_r - particles(n)%radius
294
295! NOTE: this is the correct formula (indipendent of radius).
296!       nevertheless, it give wrong results for large timesteps
297!          d_radius =  1.0 / particles(n)%radius
298!          delta_r = d_radius * ( e_a / e_s - 1.0 - 3.3E-7 / t_int * d_radius + &
299!                                 b_cond * d_radius**3 ) /                      &
300!                    ( ( l_d_rv / t_int - 1.0 ) * l_v * rho_l / t_int /         &
301!                      thermal_conductivity_l +                                 &
302!                      rho_l * r_v * t_int / diff_coeff_l / e_s ) * dt_3d
303
304!          new_r = particles(n)%radius + delta_r
305!          IF ( new_r < 1.0E-7 )  new_r = 1.0E-7
306
307!
308!--       Sum up the change in volume of liquid water for the respective grid
309!--       volume (this is needed later on for calculating the release of
310!--       latent heat)
311          i = ( particles(n)%x + 0.5 * dx ) * ddx
312          j = ( particles(n)%y + 0.5 * dy ) * ddy
313          k = particles(n)%z / dz + 1 + offset_ocean_nzt_m1
314              ! only exact if equidistant
315
316          ql_c(k,j,i) = ql_c(k,j,i) + particles(n)%weight_factor *            &
317                                      rho_l * 1.33333333 * pi *               &
318                                      ( new_r**3 - particles(n)%radius**3 ) / &
319                                      ( rho_surface * dx * dy * dz )
320          IF ( ql_c(k,j,i) > 100.0 )  THEN
321             WRITE( message_string, * ) 'k=',k,' j=',j,' i=',i, &
322                          ' ql_c=',ql_c(k,j,i), ' &part(',n,')%wf=', &
323                          particles(n)%weight_factor,' delta_r=',delta_r
324             CALL message( 'advec_particles', 'PA0143', 2, 2, 0, 6, 0 )
325          ENDIF
326
327!
328!--       Change the droplet radius
329          IF ( ( new_r - particles(n)%radius ) < 0.0  .AND.  new_r < 0.0 ) &
330          THEN
331             WRITE( message_string, * ) '#1 k=',k,' j=',j,' i=',i, &
332                          ' e_s=',e_s, ' e_a=',e_a,' t_int=',t_int, &
333                          ' &d_radius=',d_radius,' delta_r=',delta_r,&
334                          ' particle_radius=',particles(n)%radius
335             CALL message( 'advec_particles', 'PA0144', 2, 2, 0, 6, 0 )
336          ENDIF
337          particles(n)%radius = new_r
338
339!
340!--       Sum up the total volume of liquid water (needed below for
341!--       re-calculating the weighting factors)
342          ql_v(k,j,i) = ql_v(k,j,i) + particles(n)%weight_factor * &
343                                      particles(n)%radius**3
344       ENDDO
345       CALL cpu_log( log_point_s(42), 'advec_part_cond', 'stop' )
346
347!
348!--    Particle growth by collision
349       CALL cpu_log( log_point_s(43), 'advec_part_coll', 'start' )
350       
351       DO  i = nxl, nxr
352          DO  j = nys, nyn
353             DO  k = nzb+1, nzt
354!
355!--             Collision requires at least two particles in the box
356                IF ( prt_count(k,j,i) > 1 )  THEN
357!
358!--                First, sort particles within the gridbox by their size,
359!--                using Shell's method (see Numerical Recipes)
360!--                NOTE: In case of using particle tails, the re-sorting of
361!--                ----  tails would have to be included here!
362                   psi = prt_start_index(k,j,i) - 1
363                   inc = 1
364                   DO WHILE ( inc <= prt_count(k,j,i) )
365                      inc = 3 * inc + 1
366                   ENDDO
367
368                   DO WHILE ( inc > 1 )
369                      inc = inc / 3
370                      DO  is = inc+1, prt_count(k,j,i)
371                         tmp_particle = particles(psi+is)
372                         js = is
373                         DO WHILE ( particles(psi+js-inc)%radius > &
374                                    tmp_particle%radius )
375                            particles(psi+js) = particles(psi+js-inc)
376                            js = js - inc
377                            IF ( js <= inc )  EXIT
378                         ENDDO
379                         particles(psi+js) = tmp_particle
380                      ENDDO
381                   ENDDO
382
383!
384!--                Calculate the mean radius of all those particles which
385!--                are of smaller or equal size than the current particle
386!--                and use this radius for calculating the collision efficiency
387                   psi = prt_start_index(k,j,i)
388                   s_r3 = 0.0
389                   s_r4 = 0.0
390                   DO  n = psi, psi+prt_count(k,j,i)-1
391!
392!--                   There may be some particles of size equal to the
393!--                   current particle but with larger index
394                      sl_r3 = 0.0
395                      sl_r4 = 0.0
396                      DO is = n, psi+prt_count(k,j,i)-2
397                         IF ( particles(is+1)%radius == &
398                              particles(is)%radius ) THEN
399                            sl_r3 = sl_r3 + particles(is+1)%radius**3
400                            sl_r4 = sl_r4 + particles(is+1)%radius**4
401                         ELSE
402                            EXIT
403                         ENDIF
404                      ENDDO
405
406                      IF ( ( s_r3 + sl_r3 ) > 0.0 )  THEN
407
408                         mean_r = ( s_r4 + sl_r4 ) / ( s_r3 + sl_r3 )
409
410                         CALL collision_efficiency( mean_r,              &
411                                                    particles(n)%radius, &
412                                                    effective_coll_efficiency )
413
414                      ELSE
415                         effective_coll_efficiency = 0.0
416                      ENDIF
417       
418!
419!--                   Contribution of the current particle to the next one
420                      s_r3 = s_r3 + particles(n)%radius**3
421                      s_r4 = s_r4 + particles(n)%radius**4
422
423                      IF ( effective_coll_efficiency > 1.0  .OR. &
424                           effective_coll_efficiency < 0.0 )     &
425                      THEN
426                         WRITE( message_string, * )   'collision_efficiency ' , &
427                                   'out of range:' ,effective_coll_efficiency
428                         CALL message( 'advec_particles', 'PA0145', 2, 2, 0, 6, 0 )
429                      END IF
430
431!
432!--                   Interpolation of ...
433                      ii = particles(n)%x * ddx
434                      jj = particles(n)%y * ddy
435                      kk = ( particles(n)%z + 0.5 * dz ) / dz
436
437                      x  = particles(n)%x - ii * dx
438                      y  = particles(n)%y - jj * dy
439                      aa = x**2          + y**2
440                      bb = ( dx - x )**2 + y**2
441                      cc = x**2          + ( dy - y )**2
442                      dd = ( dx - x )**2 + ( dy - y )**2
443                      gg = aa + bb + cc + dd
444
445                      ql_int_l = ( ( gg-aa ) * ql(kk,jj,ii)   + ( gg-bb ) *    &
446                                                              ql(kk,jj,ii+1)   &
447                                 + ( gg-cc ) * ql(kk,jj+1,ii) + ( gg-dd ) *    &
448                                                              ql(kk,jj+1,ii+1) &
449                                 ) / ( 3.0 * gg )
450
451                      ql_int_u = ( ( gg-aa ) * ql(kk+1,jj,ii)   + ( gg-bb ) *  &
452                                                            ql(kk+1,jj,ii+1)   &
453                                 + ( gg-cc ) * ql(kk+1,jj+1,ii) + ( gg-dd ) *  &
454                                                            ql(kk+1,jj+1,ii+1) &
455                                 ) / ( 3.0 * gg )
456
457                      ql_int = ql_int_l + ( particles(n)%z - zu(kk) ) / dz * &
458                                          ( ql_int_u - ql_int_l )
459
460!
461!--                   Interpolate u velocity-component
462                      ii = ( particles(n)%x + 0.5 * dx ) * ddx
463                      jj =   particles(n)%y * ddy
464                      kk = ( particles(n)%z + 0.5 * dz ) / dz  ! only if eq.dist
465
466                      IF ( ( particles(n)%z - zu(kk) ) > ( 0.5*dz ) )  kk = kk+1
467
468                      x  = particles(n)%x + ( 0.5 - ii ) * dx
469                      y  = particles(n)%y - jj * dy
470                      aa = x**2          + y**2
471                      bb = ( dx - x )**2 + y**2
472                      cc = x**2          + ( dy - y )**2
473                      dd = ( dx - x )**2 + ( dy - y )**2
474                      gg = aa + bb + cc + dd
475
476                      u_int_l = ( ( gg-aa ) * u(kk,jj,ii)   + ( gg-bb ) *     &
477                                                              u(kk,jj,ii+1)   &
478                                + ( gg-cc ) * u(kk,jj+1,ii) + ( gg-dd ) *     &
479                                                              u(kk,jj+1,ii+1) &
480                                ) / ( 3.0 * gg ) - u_gtrans
481                      IF ( kk+1 == nzt+1 )  THEN
482                         u_int = u_int_l
483                      ELSE
484                         u_int_u = ( ( gg-aa ) * u(kk+1,jj,ii)   + ( gg-bb ) * &
485                                                             u(kk+1,jj,ii+1)   &
486                                   + ( gg-cc ) * u(kk+1,jj+1,ii) + ( gg-dd ) * &
487                                                             u(kk+1,jj+1,ii+1) &
488                                   ) / ( 3.0 * gg ) - u_gtrans
489                         u_int = u_int_l + ( particles(n)%z - zu(kk) ) / dz * &
490                                           ( u_int_u - u_int_l )
491                      ENDIF
492
493!
494!--                   Same procedure for interpolation of the v velocity-compo-
495!--                   nent (adopt index k from u velocity-component)
496                      ii =   particles(n)%x * ddx
497                      jj = ( particles(n)%y + 0.5 * dy ) * ddy
498
499                      x  = particles(n)%x - ii * dx
500                      y  = particles(n)%y + ( 0.5 - jj ) * dy
501                      aa = x**2          + y**2
502                      bb = ( dx - x )**2 + y**2
503                      cc = x**2          + ( dy - y )**2
504                      dd = ( dx - x )**2 + ( dy - y )**2
505                      gg = aa + bb + cc + dd
506
507                      v_int_l = ( ( gg-aa ) * v(kk,jj,ii)   + ( gg-bb ) *      &
508                                                               v(kk,jj,ii+1)   &
509                                + ( gg-cc ) * v(kk,jj+1,ii) + ( gg-dd ) *      &
510                                                               v(kk,jj+1,ii+1) &
511                                ) / ( 3.0 * gg ) - v_gtrans
512                      IF ( kk+1 == nzt+1 )  THEN
513                         v_int = v_int_l
514                      ELSE
515                         v_int_u = ( ( gg-aa ) * v(kk+1,jj,ii)   + ( gg-bb ) * &
516                                                               v(kk+1,jj,ii+1) &
517                                   + ( gg-cc ) * v(kk+1,jj+1,ii) + ( gg-dd ) * &
518                                                             v(kk+1,jj+1,ii+1) &
519                                ) / ( 3.0 * gg ) - v_gtrans
520                         v_int = v_int_l + ( particles(n)%z - zu(kk) ) / dz * &
521                                           ( v_int_u - v_int_l )
522                      ENDIF
523
524!
525!--                   Same procedure for interpolation of the w velocity-compo-
526!--                   nent (adopt index i from v velocity-component)
527                      jj = particles(n)%y * ddy
528                      kk = particles(n)%z / dz
529
530                      x  = particles(n)%x - ii * dx
531                      y  = particles(n)%y - jj * dy
532                      aa = x**2          + y**2
533                      bb = ( dx - x )**2 + y**2
534                      cc = x**2          + ( dy - y )**2
535                      dd = ( dx - x )**2 + ( dy - y )**2
536                      gg = aa + bb + cc + dd
537
538                      w_int_l = ( ( gg-aa ) * w(kk,jj,ii)   + ( gg-bb ) *      &
539                                                                 w(kk,jj,ii+1) &
540                                + ( gg-cc ) * w(kk,jj+1,ii) + ( gg-dd ) *      &
541                                                               w(kk,jj+1,ii+1) &
542                                ) / ( 3.0 * gg )
543                      IF ( kk+1 == nzt+1 )  THEN
544                         w_int = w_int_l
545                      ELSE
546                         w_int_u = ( ( gg-aa ) * w(kk+1,jj,ii)   + ( gg-bb ) * &
547                                                               w(kk+1,jj,ii+1) &
548                                   + ( gg-cc ) * w(kk+1,jj+1,ii) + ( gg-dd ) * &
549                                                             w(kk+1,jj+1,ii+1) &
550                                   ) / ( 3.0 * gg )
551                         w_int = w_int_l + ( particles(n)%z - zw(kk) ) / dz * &
552                                           ( w_int_u - w_int_l )
553                      ENDIF
554
555!
556!--                   Change in radius due to collision
557                      delta_r = effective_coll_efficiency * &
558                                ql_int * rho_surface / ( 1.0 - ql_int ) *   &
559                                0.25 / rho_l *                              &
560                                SQRT( ( u_int - particles(n)%speed_x )**2 + &
561                                      ( v_int - particles(n)%speed_y )**2 + &
562                                      ( w_int - particles(n)%speed_z )**2   &
563                                    ) * dt_3d
564
565                      particles(n)%radius = particles(n)%radius + delta_r
566
567                      ql_vp(k,j,i) = ql_vp(k,j,i) + particles(n)%radius**3
568
569                   ENDDO
570
571                ENDIF
572
573!
574!--             Re-calculate the weighting factor (total liquid water content
575!--             must be conserved during collision)
576                IF ( ql_vp(k,j,i) /= 0.0 )  THEN
577
578                   ql_vp(k,j,i) = ql_v(k,j,i) / ql_vp(k,j,i)
579!
580!--                Re-assign this weighting factor to the particles of the
581!--                current gridbox
582                   psi = prt_start_index(k,j,i)
583                   DO  n = psi, psi + prt_count(k,j,i)-1
584                      particles(n)%weight_factor = ql_vp(k,j,i)
585                   ENDDO
586
587                ENDIF
588
589             ENDDO
590          ENDDO
591       ENDDO
592
593       CALL cpu_log( log_point_s(43), 'advec_part_coll', 'stop' )
594
595    ENDIF
596
597
598!
599!-- Particle advection.
600!-- In case of including the SGS velocities, the LES timestep has probably
601!-- to be split into several smaller timesteps because of the Lagrangian
602!-- timescale condition. Because the number of timesteps to be carried out is
603!-- not known at the beginning, these steps are carried out in an infinite loop
604!-- with exit condition.
605!
606!-- If SGS velocities are used, gradients of the TKE have to be calculated and
607!-- boundary conditions have to be set first. Also, horizontally averaged
608!-- profiles of the SGS TKE and the resolved-scale velocity variances are
609!-- needed.
610    IF ( use_sgs_for_particles )  THEN
611
612!
613!--    TKE gradient along x and y
614       DO  i = nxl, nxr
615          DO  j = nys, nyn
616             DO  k = nzb, nzt+1
617
618                IF ( k <= nzb_s_inner(j,i-1)  .AND.  &
619                     k  > nzb_s_inner(j,i)    .AND.  &
620                     k  > nzb_s_inner(j,i+1) )  THEN
621                   de_dx(k,j,i) = 2.0 * sgs_wfu_part * &
622                                  ( e(k,j,i+1) - e(k,j,i) ) * ddx
623                ELSEIF ( k  > nzb_s_inner(j,i-1)  .AND.  &
624                         k  > nzb_s_inner(j,i)    .AND.  &
625                         k <= nzb_s_inner(j,i+1) )  THEN
626                   de_dx(k,j,i) = 2.0 * sgs_wfu_part * &
627                                  ( e(k,j,i) - e(k,j,i-1) ) * ddx
628                ELSEIF ( k < nzb_s_inner(j,i)  .AND.  k < nzb_s_inner(j,i+1) ) &
629                THEN
630                   de_dx(k,j,i) = 0.0
631                ELSEIF ( k < nzb_s_inner(j,i-1)  .AND.  k < nzb_s_inner(j,i) ) &
632                THEN
633                   de_dx(k,j,i) = 0.0
634                ELSE
635                   de_dx(k,j,i) = sgs_wfu_part * &
636                                  ( e(k,j,i+1) - e(k,j,i-1) ) * ddx
637                ENDIF
638
639                IF ( k <= nzb_s_inner(j-1,i)  .AND.  &
640                     k  > nzb_s_inner(j,i)    .AND.  &
641                     k  > nzb_s_inner(j+1,i) )  THEN
642                   de_dy(k,j,i) = 2.0 * sgs_wfv_part * &
643                                  ( e(k,j+1,i) - e(k,j,i) ) * ddy
644                ELSEIF ( k  > nzb_s_inner(j-1,i)  .AND.  &
645                         k  > nzb_s_inner(j,i)    .AND.  &
646                         k <= nzb_s_inner(j+1,i) )  THEN
647                   de_dy(k,j,i) = 2.0 * sgs_wfv_part * &
648                                  ( e(k,j,i) - e(k,j-1,i) ) * ddy
649                ELSEIF ( k < nzb_s_inner(j,i)  .AND.  k < nzb_s_inner(j+1,i) ) &
650                THEN
651                   de_dy(k,j,i) = 0.0
652                ELSEIF ( k < nzb_s_inner(j-1,i)  .AND.  k < nzb_s_inner(j,i) ) &
653                THEN
654                   de_dy(k,j,i) = 0.0
655                ELSE
656                   de_dy(k,j,i) = sgs_wfv_part * &
657                                  ( e(k,j+1,i) - e(k,j-1,i) ) * ddy
658                ENDIF
659
660             ENDDO
661          ENDDO
662       ENDDO
663
664!
665!--    TKE gradient along z, including bottom and top boundary conditions
666       DO  i = nxl, nxr
667          DO  j = nys, nyn
668
669             DO  k = nzb_s_inner(j,i)+2, nzt-1
670                de_dz(k,j,i) = 2.0 * sgs_wfw_part * &
671                               ( e(k+1,j,i) - e(k-1,j,i) ) / ( zu(k+1)-zu(k-1) )
672             ENDDO
673
674             k = nzb_s_inner(j,i)
675             de_dz(nzb:k,j,i)   = 0.0
676             de_dz(k+1,j,i) = 2.0 * sgs_wfw_part * ( e(k+2,j,i) - e(k+1,j,i) ) &
677                                                 / ( zu(k+2) - zu(k+1) )
678             de_dz(nzt,j,i)   = 0.0
679             de_dz(nzt+1,j,i) = 0.0
680          ENDDO
681       ENDDO
682
683!
684!--    Lateral boundary conditions
685       CALL exchange_horiz( de_dx )
686       CALL exchange_horiz( de_dy )
687       CALL exchange_horiz( de_dz )
688       CALL exchange_horiz( diss  )
689
690!
691!--    Calculate the horizontally averaged profiles of SGS TKE and resolved
692!--    velocity variances (they may have been already calculated in routine
693!--    flow_statistics).
694       IF ( .NOT. flow_statistics_called )  THEN
695!
696!--       First calculate horizontally averaged profiles of the horizontal
697!--       velocities.
698          sums_l(:,1,0) = 0.0
699          sums_l(:,2,0) = 0.0
700
701          DO  i = nxl, nxr
702             DO  j =  nys, nyn
703                DO  k = nzb_s_outer(j,i), nzt+1
704                   sums_l(k,1,0)  = sums_l(k,1,0)  + u(k,j,i)
705                   sums_l(k,2,0)  = sums_l(k,2,0)  + v(k,j,i)
706                ENDDO
707             ENDDO
708          ENDDO
709
710#if defined( __parallel )
711!
712!--       Compute total sum from local sums
713          CALL MPI_ALLREDUCE( sums_l(nzb,1,0), sums(nzb,1), nzt+2-nzb, &
714                              MPI_REAL, MPI_SUM, comm2d, ierr )
715          CALL MPI_ALLREDUCE( sums_l(nzb,2,0), sums(nzb,2), nzt+2-nzb, &
716                              MPI_REAL, MPI_SUM, comm2d, ierr )
717#else
718                   sums(:,1) = sums_l(:,1,0)
719                   sums(:,2) = sums_l(:,2,0)
720#endif
721
722!
723!--       Final values are obtained by division by the total number of grid
724!--       points used for the summation.
725          hom(:,1,1,0) = sums(:,1) / ngp_2dh_outer(:,0)   ! u
726          hom(:,1,2,0) = sums(:,2) / ngp_2dh_outer(:,0)   ! v
727
728!
729!--       Now calculate the profiles of SGS TKE and the resolved-scale
730!--       velocity variances
731          sums_l(:,8,0)  = 0.0
732          sums_l(:,30,0) = 0.0
733          sums_l(:,31,0) = 0.0
734          sums_l(:,32,0) = 0.0
735          DO  i = nxl, nxr
736             DO  j = nys, nyn
737                DO  k = nzb_s_outer(j,i), nzt+1
738                   sums_l(k,8,0)  = sums_l(k,8,0)  + e(k,j,i)
739                   sums_l(k,30,0) = sums_l(k,30,0) + &
740                                    ( u(k,j,i) - hom(k,1,1,0) )**2
741                   sums_l(k,31,0) = sums_l(k,31,0) + &
742                                    ( v(k,j,i) - hom(k,1,2,0) )**2
743                   sums_l(k,32,0) = sums_l(k,32,0) + w(k,j,i)**2
744                ENDDO
745             ENDDO
746          ENDDO
747
748#if defined( __parallel )
749!
750!--       Compute total sum from local sums
751          CALL MPI_ALLREDUCE( sums_l(nzb,8,0), sums(nzb,8), nzt+2-nzb, &
752                              MPI_REAL, MPI_SUM, comm2d, ierr )
753          CALL MPI_ALLREDUCE( sums_l(nzb,30,0), sums(nzb,30), nzt+2-nzb, &
754                              MPI_REAL, MPI_SUM, comm2d, ierr )
755          CALL MPI_ALLREDUCE( sums_l(nzb,31,0), sums(nzb,31), nzt+2-nzb, &
756                              MPI_REAL, MPI_SUM, comm2d, ierr )
757          CALL MPI_ALLREDUCE( sums_l(nzb,32,0), sums(nzb,32), nzt+2-nzb, &
758                              MPI_REAL, MPI_SUM, comm2d, ierr )
759                 
760#else
761          sums(:,8)  = sums_l(:,8,0)
762          sums(:,30) = sums_l(:,30,0)
763          sums(:,31) = sums_l(:,31,0)
764          sums(:,32) = sums_l(:,32,0)
765#endif
766
767!
768!--       Final values are obtained by division by the total number of grid
769!--       points used for the summation.
770          hom(:,1,8,0)  = sums(:,8)  / ngp_2dh_outer(:,0)   ! e
771          hom(:,1,30,0) = sums(:,30) / ngp_2dh_outer(:,0)   ! u*2
772          hom(:,1,31,0) = sums(:,31) / ngp_2dh_outer(:,0)   ! v*2
773          hom(:,1,32,0) = sums(:,32) / ngp_2dh_outer(:,0)   ! w*2
774
775       ENDIF
776
777    ENDIF 
778
779!
780!-- Initialize variables used for accumulating the number of particles
781!-- exchanged between the subdomains during all sub-timesteps (if sgs
782!-- velocities are included). These data are output further below on the
783!-- particle statistics file.
784    trlp_count_sum      = 0
785    trlp_count_recv_sum = 0
786    trrp_count_sum      = 0
787    trrp_count_recv_sum = 0
788    trsp_count_sum      = 0
789    trsp_count_recv_sum = 0
790    trnp_count_sum      = 0
791    trnp_count_recv_sum = 0
792
793!
794!-- Initialize the variable storing the total time that a particle has advanced
795!-- within the timestep procedure
796    particles(1:number_of_particles)%dt_sum = 0.0
797
798!
799!-- Timestep loop.
800!-- This loop has to be repeated until the advection time of every particle
801!-- (in the total domain!) has reached the LES timestep (dt_3d)
802    DO
803
804       CALL cpu_log( log_point_s(44), 'advec_part_advec', 'start' )
805
806!
807!--    Initialize the switch used for the loop exit condition checked at the
808!--    end of this loop.
809!--    If at least one particle has failed to reach the LES timestep, this
810!--    switch will be set false.
811       dt_3d_reached_l = .TRUE.
812
813!
814!--    Initialize variables for the (sub-) timestep, i.e. for marking those
815!--    particles to be deleted after the timestep
816       particle_mask     = .TRUE.
817       deleted_particles = 0
818       trlp_count_recv   = 0
819       trnp_count_recv   = 0
820       trrp_count_recv   = 0
821       trsp_count_recv   = 0
822       trlpt_count_recv  = 0
823       trnpt_count_recv  = 0
824       trrpt_count_recv  = 0
825       trspt_count_recv  = 0
826       IF ( use_particle_tails )  THEN
827          tail_mask     = .TRUE.
828       ENDIF
829       deleted_tails = 0
830
831
832       DO  n = 1, number_of_particles
833!
834!--       Move particles only if the LES timestep has not (approximately) been
835!--       reached
836          IF ( ( dt_3d - particles(n)%dt_sum ) < 1E-8 )  CYCLE
837
838!
839!--       Interpolate u velocity-component, determine left, front, bottom
840!--       index of u-array
841          i = ( particles(n)%x + 0.5 * dx ) * ddx
842          j =   particles(n)%y * ddy
843          k = ( particles(n)%z + 0.5 * dz * atmos_ocean_sign ) / dz  &
844              + offset_ocean_nzt                     ! only exact if equidistant
845                                               
846!
847!--       Interpolation of the velocity components in the xy-plane
848          x  = particles(n)%x + ( 0.5 - i ) * dx
849          y  = particles(n)%y - j * dy
850          aa = x**2          + y**2
851          bb = ( dx - x )**2 + y**2
852          cc = x**2          + ( dy - y )**2
853          dd = ( dx - x )**2 + ( dy - y )**2
854          gg = aa + bb + cc + dd
855
856          u_int_l = ( ( gg - aa ) * u(k,j,i)   + ( gg - bb ) * u(k,j,i+1)   &
857                    + ( gg - cc ) * u(k,j+1,i) + ( gg - dd ) * u(k,j+1,i+1) &
858                    ) / ( 3.0 * gg ) - u_gtrans
859          IF ( k+1 == nzt+1 )  THEN
860             u_int = u_int_l
861          ELSE
862             u_int_u = ( ( gg-aa ) * u(k+1,j,i)   + ( gg-bb ) * u(k+1,j,i+1) &
863                    + ( gg-cc ) * u(k+1,j+1,i) + ( gg-dd ) * u(k+1,j+1,i+1)  &
864                    ) / ( 3.0 * gg ) - u_gtrans
865             u_int = u_int_l + ( particles(n)%z - zu(k) ) / dz * &
866                               ( u_int_u - u_int_l )
867          ENDIF
868
869!
870!--       Same procedure for interpolation of the v velocity-component (adopt
871!--       index k from u velocity-component)
872          i =   particles(n)%x * ddx
873          j = ( particles(n)%y + 0.5 * dy ) * ddy
874
875          x  = particles(n)%x - i * dx
876          y  = particles(n)%y + ( 0.5 - j ) * dy
877          aa = x**2          + y**2
878          bb = ( dx - x )**2 + y**2
879          cc = x**2          + ( dy - y )**2
880          dd = ( dx - x )**2 + ( dy - y )**2
881          gg = aa + bb + cc + dd
882
883          v_int_l = ( ( gg - aa ) * v(k,j,i)   + ( gg - bb ) * v(k,j,i+1)   &
884                    + ( gg - cc ) * v(k,j+1,i) + ( gg - dd ) * v(k,j+1,i+1) &
885                    ) / ( 3.0 * gg ) - v_gtrans
886          IF ( k+1 == nzt+1 )  THEN
887             v_int = v_int_l
888          ELSE
889             v_int_u = ( ( gg-aa ) * v(k+1,j,i)   + ( gg-bb ) * v(k+1,j,i+1) &
890                    + ( gg-cc ) * v(k+1,j+1,i) + ( gg-dd ) * v(k+1,j+1,i+1)  &
891                    ) / ( 3.0 * gg ) - v_gtrans
892             v_int = v_int_l + ( particles(n)%z - zu(k) ) / dz * &
893                               ( v_int_u - v_int_l )
894          ENDIF
895
896!
897!--       Same procedure for interpolation of the w velocity-component (adopt
898!--       index i from v velocity-component)
899          IF ( vertical_particle_advection )  THEN
900             j = particles(n)%y * ddy
901             k = particles(n)%z / dz + offset_ocean_nzt_m1
902
903             x  = particles(n)%x - i * dx
904             y  = particles(n)%y - j * dy
905             aa = x**2          + y**2
906             bb = ( dx - x )**2 + y**2
907             cc = x**2          + ( dy - y )**2
908             dd = ( dx - x )**2 + ( dy - y )**2
909             gg = aa + bb + cc + dd
910
911             w_int_l = ( ( gg - aa ) * w(k,j,i)   + ( gg - bb ) * w(k,j,i+1) &
912                    + ( gg - cc ) * w(k,j+1,i) + ( gg - dd ) * w(k,j+1,i+1)  &
913                       ) / ( 3.0 * gg )
914             IF ( k+1 == nzt+1 )  THEN
915                w_int = w_int_l
916             ELSE
917                w_int_u = ( ( gg-aa ) * w(k+1,j,i)   + &
918                            ( gg-bb ) * w(k+1,j,i+1) + &
919                            ( gg-cc ) * w(k+1,j+1,i) + &
920                            ( gg-dd ) * w(k+1,j+1,i+1) &
921                           ) / ( 3.0 * gg )
922                w_int = w_int_l + ( particles(n)%z - zw(k) ) / dz * &
923                                  ( w_int_u - w_int_l )
924             ENDIF
925          ELSE
926             w_int = 0.0
927          ENDIF
928
929!
930!--       Interpolate and calculate quantities needed for calculating the SGS
931!--       velocities
932          IF ( use_sgs_for_particles )  THEN
933!
934!--          Interpolate TKE
935             i = particles(n)%x * ddx
936             j = particles(n)%y * ddy
937             k = ( particles(n)%z + 0.5 * dz * atmos_ocean_sign ) / dz  &
938                 + offset_ocean_nzt                      ! only exact if eq.dist
939
940             IF ( topography == 'flat' )  THEN       
941
942                x  = particles(n)%x - i * dx
943                y  = particles(n)%y - j * dy
944                aa = x**2          + y**2
945                bb = ( dx - x )**2 + y**2
946                cc = x**2          + ( dy - y )**2
947                dd = ( dx - x )**2 + ( dy - y )**2
948                gg = aa + bb + cc + dd
949
950                e_int_l = ( ( gg-aa ) * e(k,j,i)   + ( gg-bb ) * e(k,j,i+1)   &
951                          + ( gg-cc ) * e(k,j+1,i) + ( gg-dd ) * e(k,j+1,i+1) &
952                          ) / ( 3.0 * gg )
953
954                IF ( k+1 == nzt+1 )  THEN
955                   e_int = e_int_l
956                ELSE
957                   e_int_u = ( ( gg - aa ) * e(k+1,j,i)   + &
958                               ( gg - bb ) * e(k+1,j,i+1) + &
959                               ( gg - cc ) * e(k+1,j+1,i) + &
960                               ( gg - dd ) * e(k+1,j+1,i+1) &
961                             ) / ( 3.0 * gg )
962                   e_int = e_int_l + ( particles(n)%z - zu(k) ) / dz * &
963                                     ( e_int_u - e_int_l )
964                ENDIF
965
966!
967!--             Interpolate the TKE gradient along x (adopt incides i,j,k and
968!--             all position variables from above (TKE))
969                de_dx_int_l = ( ( gg - aa ) * de_dx(k,j,i)   + &
970                                ( gg - bb ) * de_dx(k,j,i+1) + &
971                                ( gg - cc ) * de_dx(k,j+1,i) + &
972                                ( gg - dd ) * de_dx(k,j+1,i+1) &
973                              ) / ( 3.0 * gg )
974
975                IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
976                   de_dx_int = de_dx_int_l
977                ELSE
978                   de_dx_int_u = ( ( gg - aa ) * de_dx(k+1,j,i)   + &
979                                   ( gg - bb ) * de_dx(k+1,j,i+1) + &
980                                   ( gg - cc ) * de_dx(k+1,j+1,i) + &
981                                   ( gg - dd ) * de_dx(k+1,j+1,i+1) &
982                                 ) / ( 3.0 * gg )
983                   de_dx_int = de_dx_int_l + ( particles(n)%z - zu(k) ) / dz * &
984                                             ( de_dx_int_u - de_dx_int_l )
985                ENDIF
986
987!
988!--             Interpolate the TKE gradient along y
989                de_dy_int_l = ( ( gg - aa ) * de_dy(k,j,i)   + &
990                                ( gg - bb ) * de_dy(k,j,i+1) + &
991                                ( gg - cc ) * de_dy(k,j+1,i) + &
992                                ( gg - dd ) * de_dy(k,j+1,i+1) &
993                              ) / ( 3.0 * gg )
994                IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
995                   de_dy_int = de_dy_int_l
996                ELSE
997                   de_dy_int_u = ( ( gg - aa ) * de_dy(k+1,j,i)   + &
998                                   ( gg - bb ) * de_dy(k+1,j,i+1) + &
999                                   ( gg - cc ) * de_dy(k+1,j+1,i) + &
1000                                   ( gg - dd ) * de_dy(k+1,j+1,i+1) &
1001                                 ) / ( 3.0 * gg )
1002                   de_dy_int = de_dy_int_l + ( particles(n)%z - zu(k) ) / dz * &
1003                                             ( de_dy_int_u - de_dy_int_l )
1004                ENDIF
1005
1006!
1007!--             Interpolate the TKE gradient along z
1008                IF ( particles(n)%z < 0.5 * dz ) THEN
1009                   de_dz_int = 0.0
1010                ELSE
1011                   de_dz_int_l = ( ( gg - aa ) * de_dz(k,j,i)   + &
1012                                   ( gg - bb ) * de_dz(k,j,i+1) + &
1013                                   ( gg - cc ) * de_dz(k,j+1,i) + &
1014                                   ( gg - dd ) * de_dz(k,j+1,i+1) &
1015                                 ) / ( 3.0 * gg )
1016
1017                   IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
1018                      de_dz_int = de_dz_int_l
1019                   ELSE
1020                      de_dz_int_u = ( ( gg - aa ) * de_dz(k+1,j,i)   + &
1021                                      ( gg - bb ) * de_dz(k+1,j,i+1) + &
1022                                      ( gg - cc ) * de_dz(k+1,j+1,i) + &
1023                                      ( gg - dd ) * de_dz(k+1,j+1,i+1) &
1024                                    ) / ( 3.0 * gg )
1025                      de_dz_int = de_dz_int_l + ( particles(n)%z - zu(k) ) / dz * &
1026                                                ( de_dz_int_u - de_dz_int_l )
1027                   ENDIF
1028                ENDIF
1029
1030!
1031!--             Interpolate the dissipation of TKE
1032                diss_int_l = ( ( gg - aa ) * diss(k,j,i)   + &
1033                               ( gg - bb ) * diss(k,j,i+1) + &
1034                               ( gg - cc ) * diss(k,j+1,i) + &
1035                               ( gg - dd ) * diss(k,j+1,i+1) &
1036                              ) / ( 3.0 * gg )
1037
1038                IF ( k+1 == nzt+1 )  THEN
1039                   diss_int = diss_int_l
1040                ELSE
1041                   diss_int_u = ( ( gg - aa ) * diss(k+1,j,i)   + &
1042                                  ( gg - bb ) * diss(k+1,j,i+1) + &
1043                                  ( gg - cc ) * diss(k+1,j+1,i) + &
1044                                  ( gg - dd ) * diss(k+1,j+1,i+1) &
1045                                 ) / ( 3.0 * gg )
1046                   diss_int = diss_int_l + ( particles(n)%z - zu(k) ) / dz * &
1047                                           ( diss_int_u - diss_int_l )
1048                ENDIF
1049
1050             ELSE
1051
1052!
1053!--             In case that there are buildings it has to be determined
1054!--             how many of the gridpoints defining the particle box are
1055!--             situated within a building
1056!--             gp_outside_of_building(1): i,j,k
1057!--             gp_outside_of_building(2): i,j+1,k
1058!--             gp_outside_of_building(3): i,j,k+1
1059!--             gp_outside_of_building(4): i,j+1,k+1
1060!--             gp_outside_of_building(5): i+1,j,k
1061!--             gp_outside_of_building(6): i+1,j+1,k
1062!--             gp_outside_of_building(7): i+1,j,k+1
1063!--             gp_outside_of_building(8): i+1,j+1,k+1
1064           
1065                gp_outside_of_building = 0
1066                location = 0.0
1067                num_gp = 0
1068
1069                IF ( k > nzb_s_inner(j,i)  .OR.  nzb_s_inner(j,i) == 0 )  THEN
1070                   num_gp = num_gp + 1
1071                   gp_outside_of_building(1) = 1
1072                   location(num_gp,1) = i * dx
1073                   location(num_gp,2) = j * dy
1074                   location(num_gp,3) = k * dz - 0.5 * dz
1075                   ei(num_gp)     = e(k,j,i)
1076                   dissi(num_gp)  = diss(k,j,i)
1077                   de_dxi(num_gp) = de_dx(k,j,i)
1078                   de_dyi(num_gp) = de_dy(k,j,i)
1079                   de_dzi(num_gp) = de_dz(k,j,i)
1080                ENDIF
1081
1082                IF ( k > nzb_s_inner(j+1,i)  .OR.  nzb_s_inner(j+1,i) == 0 ) &
1083                THEN
1084                   num_gp = num_gp + 1
1085                   gp_outside_of_building(2) = 1
1086                   location(num_gp,1) = i * dx
1087                   location(num_gp,2) = (j+1) * dy
1088                   location(num_gp,3) = k * dz - 0.5 * dz
1089                   ei(num_gp)     = e(k,j+1,i)
1090                   dissi(num_gp)  = diss(k,j+1,i)       
1091                   de_dxi(num_gp) = de_dx(k,j+1,i)
1092                   de_dyi(num_gp) = de_dy(k,j+1,i)
1093                   de_dzi(num_gp) = de_dz(k,j+1,i)
1094                ENDIF
1095
1096                IF ( k+1 > nzb_s_inner(j,i)  .OR.  nzb_s_inner(j,i) == 0 )  THEN
1097                   num_gp = num_gp + 1
1098                   gp_outside_of_building(3) = 1
1099                   location(num_gp,1) = i * dx
1100                   location(num_gp,2) = j * dy
1101                   location(num_gp,3) = (k+1) * dz - 0.5 * dz
1102                   ei(num_gp)     = e(k+1,j,i)
1103                   dissi(num_gp)  = diss(k+1,j,i)       
1104                   de_dxi(num_gp) = de_dx(k+1,j,i)
1105                   de_dyi(num_gp) = de_dy(k+1,j,i)
1106                   de_dzi(num_gp) = de_dz(k+1,j,i)
1107                ENDIF
1108
1109                IF ( k+1 > nzb_s_inner(j+1,i)  .OR.  nzb_s_inner(j+1,i) == 0 ) &
1110                THEN
1111                   num_gp = num_gp + 1
1112                   gp_outside_of_building(4) = 1
1113                   location(num_gp,1) = i * dx
1114                   location(num_gp,2) = (j+1) * dy
1115                   location(num_gp,3) = (k+1) * dz - 0.5 * dz
1116                   ei(num_gp)     = e(k+1,j+1,i)
1117                   dissi(num_gp)  = diss(k+1,j+1,i)       
1118                   de_dxi(num_gp) = de_dx(k+1,j+1,i)
1119                   de_dyi(num_gp) = de_dy(k+1,j+1,i)
1120                   de_dzi(num_gp) = de_dz(k+1,j+1,i)
1121                ENDIF
1122 
1123                IF ( k > nzb_s_inner(j,i+1)  .OR.  nzb_s_inner(j,i+1) == 0 ) &
1124                THEN
1125                   num_gp = num_gp + 1
1126                   gp_outside_of_building(5) = 1
1127                   location(num_gp,1) = (i+1) * dx
1128                   location(num_gp,2) = j * dy
1129                   location(num_gp,3) = k * dz - 0.5 * dz
1130                   ei(num_gp)     = e(k,j,i+1)
1131                   dissi(num_gp)  = diss(k,j,i+1) 
1132                   de_dxi(num_gp) = de_dx(k,j,i+1)
1133                   de_dyi(num_gp) = de_dy(k,j,i+1)
1134                   de_dzi(num_gp) = de_dz(k,j,i+1)
1135                ENDIF
1136
1137                IF ( k > nzb_s_inner(j+1,i+1) .OR. nzb_s_inner(j+1,i+1) == 0 ) &
1138                THEN
1139                   num_gp = num_gp + 1
1140                   gp_outside_of_building(6) = 1
1141                   location(num_gp,1) = (i+1) * dx
1142                   location(num_gp,2) = (j+1) * dy
1143                   location(num_gp,3) = k * dz - 0.5 * dz
1144                   ei(num_gp)     = e(k,j+1,i+1)
1145                   dissi(num_gp)  = diss(k,j+1,i+1) 
1146                   de_dxi(num_gp) = de_dx(k,j+1,i+1)
1147                   de_dyi(num_gp) = de_dy(k,j+1,i+1)
1148                   de_dzi(num_gp) = de_dz(k,j+1,i+1)
1149                ENDIF
1150
1151                IF ( k+1 > nzb_s_inner(j,i+1)  .OR.  nzb_s_inner(j,i+1) == 0 ) &
1152                THEN
1153                   num_gp = num_gp + 1
1154                   gp_outside_of_building(7) = 1
1155                   location(num_gp,1) = (i+1) * dx
1156                   location(num_gp,2) = j * dy
1157                   location(num_gp,3) = (k+1) * dz - 0.5 * dz
1158                   ei(num_gp)     = e(k+1,j,i+1)
1159                   dissi(num_gp)  = diss(k+1,j,i+1) 
1160                   de_dxi(num_gp) = de_dx(k+1,j,i+1)
1161                   de_dyi(num_gp) = de_dy(k+1,j,i+1)
1162                   de_dzi(num_gp) = de_dz(k+1,j,i+1)
1163                ENDIF
1164
1165                IF ( k+1 > nzb_s_inner(j+1,i+1) .OR. nzb_s_inner(j+1,i+1) == 0)&
1166                THEN
1167                   num_gp = num_gp + 1
1168                   gp_outside_of_building(8) = 1
1169                   location(num_gp,1) = (i+1) * dx
1170                   location(num_gp,2) = (j+1) * dy
1171                   location(num_gp,3) = (k+1) * dz - 0.5 * dz
1172                   ei(num_gp)     = e(k+1,j+1,i+1)
1173                   dissi(num_gp)  = diss(k+1,j+1,i+1) 
1174                   de_dxi(num_gp) = de_dx(k+1,j+1,i+1)
1175                   de_dyi(num_gp) = de_dy(k+1,j+1,i+1)
1176                   de_dzi(num_gp) = de_dz(k+1,j+1,i+1)
1177                ENDIF
1178
1179!
1180!--             If all gridpoints are situated outside of a building, then the
1181!--             ordinary interpolation scheme can be used.
1182                IF ( num_gp == 8 )  THEN
1183
1184                   x  = particles(n)%x - i * dx
1185                   y  = particles(n)%y - j * dy
1186                   aa = x**2          + y**2
1187                   bb = ( dx - x )**2 + y**2
1188                   cc = x**2          + ( dy - y )**2
1189                   dd = ( dx - x )**2 + ( dy - y )**2
1190                   gg = aa + bb + cc + dd
1191
1192                   e_int_l = (( gg-aa ) * e(k,j,i)   + ( gg-bb ) * e(k,j,i+1) &
1193                            + ( gg-cc ) * e(k,j+1,i) + ( gg-dd ) * e(k,j+1,i+1)&
1194                             ) / ( 3.0 * gg )
1195
1196                   IF ( k+1 == nzt+1 )  THEN
1197                      e_int = e_int_l
1198                   ELSE
1199                      e_int_u = ( ( gg - aa ) * e(k+1,j,i)   + &
1200                                  ( gg - bb ) * e(k+1,j,i+1) + &
1201                                  ( gg - cc ) * e(k+1,j+1,i) + &
1202                                  ( gg - dd ) * e(k+1,j+1,i+1) &
1203                                ) / ( 3.0 * gg )
1204                      e_int = e_int_l + ( particles(n)%z - zu(k) ) / dz * &
1205                                        ( e_int_u - e_int_l )
1206                   ENDIF
1207
1208!
1209!--                Interpolate the TKE gradient along x (adopt incides i,j,k
1210!--                and all position variables from above (TKE))
1211                   de_dx_int_l = ( ( gg - aa ) * de_dx(k,j,i)   + &
1212                                   ( gg - bb ) * de_dx(k,j,i+1) + &
1213                                   ( gg - cc ) * de_dx(k,j+1,i) + &
1214                                   ( gg - dd ) * de_dx(k,j+1,i+1) &
1215                                 ) / ( 3.0 * gg )
1216
1217                   IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
1218                      de_dx_int = de_dx_int_l
1219                   ELSE
1220                      de_dx_int_u = ( ( gg - aa ) * de_dx(k+1,j,i)   + &
1221                                      ( gg - bb ) * de_dx(k+1,j,i+1) + &
1222                                      ( gg - cc ) * de_dx(k+1,j+1,i) + &
1223                                      ( gg - dd ) * de_dx(k+1,j+1,i+1) &
1224                                    ) / ( 3.0 * gg )
1225                      de_dx_int = de_dx_int_l + ( particles(n)%z - zu(k) ) / &
1226                                              dz * ( de_dx_int_u - de_dx_int_l )
1227                   ENDIF
1228
1229!
1230!--                Interpolate the TKE gradient along y
1231                   de_dy_int_l = ( ( gg - aa ) * de_dy(k,j,i)   + &
1232                                   ( gg - bb ) * de_dy(k,j,i+1) + &
1233                                   ( gg - cc ) * de_dy(k,j+1,i) + &
1234                                   ( gg - dd ) * de_dy(k,j+1,i+1) &
1235                                 ) / ( 3.0 * gg )
1236                   IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
1237                      de_dy_int = de_dy_int_l
1238                   ELSE
1239                      de_dy_int_u = ( ( gg - aa ) * de_dy(k+1,j,i)   + &
1240                                      ( gg - bb ) * de_dy(k+1,j,i+1) + &
1241                                      ( gg - cc ) * de_dy(k+1,j+1,i) + &
1242                                      ( gg - dd ) * de_dy(k+1,j+1,i+1) &
1243                                    ) / ( 3.0 * gg )
1244                      de_dy_int = de_dy_int_l + ( particles(n)%z - zu(k) ) / &
1245                                              dz * ( de_dy_int_u - de_dy_int_l )
1246                   ENDIF
1247
1248!
1249!--                Interpolate the TKE gradient along z
1250                   IF ( particles(n)%z < 0.5 * dz )  THEN
1251                      de_dz_int = 0.0
1252                   ELSE
1253                      de_dz_int_l = ( ( gg - aa ) * de_dz(k,j,i)   + &
1254                                      ( gg - bb ) * de_dz(k,j,i+1) + &
1255                                      ( gg - cc ) * de_dz(k,j+1,i) + &
1256                                      ( gg - dd ) * de_dz(k,j+1,i+1) &
1257                                    ) / ( 3.0 * gg )
1258
1259                      IF ( ( k+1 == nzt+1 )  .OR.  ( k == nzb ) )  THEN
1260                         de_dz_int = de_dz_int_l
1261                      ELSE
1262                         de_dz_int_u = ( ( gg - aa ) * de_dz(k+1,j,i)   + &
1263                                         ( gg - bb ) * de_dz(k+1,j,i+1) + &
1264                                         ( gg - cc ) * de_dz(k+1,j+1,i) + &
1265                                         ( gg - dd ) * de_dz(k+1,j+1,i+1) &
1266                                       ) / ( 3.0 * gg )
1267                         de_dz_int = de_dz_int_l + ( particles(n)%z - zu(k) ) /&
1268                                              dz * ( de_dz_int_u - de_dz_int_l )
1269                      ENDIF
1270                   ENDIF
1271
1272!
1273!--                Interpolate the dissipation of TKE
1274                   diss_int_l = ( ( gg - aa ) * diss(k,j,i)   + &
1275                                  ( gg - bb ) * diss(k,j,i+1) + &
1276                                  ( gg - cc ) * diss(k,j+1,i) + &
1277                                  ( gg - dd ) * diss(k,j+1,i+1) &
1278                                ) / ( 3.0 * gg )
1279
1280                   IF ( k+1 == nzt+1 )  THEN
1281                      diss_int = diss_int_l
1282                   ELSE
1283                      diss_int_u = ( ( gg - aa ) * diss(k+1,j,i)   + &
1284                                     ( gg - bb ) * diss(k+1,j,i+1) + &
1285                                     ( gg - cc ) * diss(k+1,j+1,i) + &
1286                                     ( gg - dd ) * diss(k+1,j+1,i+1) &
1287                                   ) / ( 3.0 * gg )
1288                      diss_int = diss_int_l + ( particles(n)%z - zu(k) ) / dz *&
1289                                              ( diss_int_u - diss_int_l )
1290                   ENDIF
1291
1292                ELSE
1293
1294!
1295!--                If wall between gridpoint 1 and gridpoint 5, then
1296!--                Neumann boundary condition has to be applied
1297                   IF ( gp_outside_of_building(1) == 1  .AND. &
1298                        gp_outside_of_building(5) == 0 )  THEN
1299                      num_gp = num_gp + 1
1300                      location(num_gp,1) = i * dx + 0.5 * dx
1301                      location(num_gp,2) = j * dy
1302                      location(num_gp,3) = k * dz - 0.5 * dz
1303                      ei(num_gp)     = e(k,j,i)
1304                      dissi(num_gp)  = diss(k,j,i)
1305                      de_dxi(num_gp) = 0.0
1306                      de_dyi(num_gp) = de_dy(k,j,i)
1307                      de_dzi(num_gp) = de_dz(k,j,i)                     
1308                   ENDIF
1309   
1310                   IF ( gp_outside_of_building(5) == 1  .AND. &
1311                      gp_outside_of_building(1) == 0 )  THEN
1312                      num_gp = num_gp + 1
1313                      location(num_gp,1) = i * dx + 0.5 * dx
1314                      location(num_gp,2) = j * dy
1315                      location(num_gp,3) = k * dz - 0.5 * dz
1316                      ei(num_gp)     = e(k,j,i+1)
1317                      dissi(num_gp)  = diss(k,j,i+1)
1318                      de_dxi(num_gp) = 0.0
1319                      de_dyi(num_gp) = de_dy(k,j,i+1)
1320                      de_dzi(num_gp) = de_dz(k,j,i+1)
1321                   ENDIF
1322
1323!
1324!--                If wall between gridpoint 5 and gridpoint 6, then
1325!--                then Neumann boundary condition has to be applied
1326                   IF ( gp_outside_of_building(5) == 1  .AND. &
1327                        gp_outside_of_building(6) == 0 )  THEN
1328                      num_gp = num_gp + 1
1329                      location(num_gp,1) = (i+1) * dx
1330                      location(num_gp,2) = j * dy + 0.5 * dy
1331                      location(num_gp,3) = k * dz - 0.5 * dz
1332                      ei(num_gp)     = e(k,j,i+1)
1333                      dissi(num_gp)  = diss(k,j,i+1)
1334                      de_dxi(num_gp) = de_dx(k,j,i+1)
1335                      de_dyi(num_gp) = 0.0
1336                      de_dzi(num_gp) = de_dz(k,j,i+1)
1337                   ENDIF
1338
1339                   IF ( gp_outside_of_building(6) == 1  .AND. &
1340                        gp_outside_of_building(5) == 0 )  THEN
1341                      num_gp = num_gp + 1
1342                      location(num_gp,1) = (i+1) * dx
1343                      location(num_gp,2) = j * dy + 0.5 * dy
1344                      location(num_gp,3) = k * dz - 0.5 * dz
1345                      ei(num_gp)     = e(k,j+1,i+1)
1346                      dissi(num_gp)  = diss(k,j+1,i+1)
1347                      de_dxi(num_gp) = de_dx(k,j+1,i+1)
1348                      de_dyi(num_gp) = 0.0
1349                      de_dzi(num_gp) = de_dz(k,j+1,i+1)
1350                   ENDIF
1351
1352!
1353!--                If wall between gridpoint 2 and gridpoint 6, then
1354!--                Neumann boundary condition has to be applied
1355                   IF ( gp_outside_of_building(2) == 1  .AND. &
1356                        gp_outside_of_building(6) == 0 )  THEN
1357                      num_gp = num_gp + 1
1358                      location(num_gp,1) = i * dx + 0.5 * dx
1359                      location(num_gp,2) = (j+1) * dy
1360                      location(num_gp,3) = k * dz - 0.5 * dz
1361                      ei(num_gp)     = e(k,j+1,i)
1362                      dissi(num_gp)  = diss(k,j+1,i)
1363                      de_dxi(num_gp) = 0.0
1364                      de_dyi(num_gp) = de_dy(k,j+1,i)
1365                      de_dzi(num_gp) = de_dz(k,j+1,i)                     
1366                   ENDIF
1367   
1368                   IF ( gp_outside_of_building(6) == 1  .AND. &
1369                        gp_outside_of_building(2) == 0 )  THEN
1370                      num_gp = num_gp + 1
1371                      location(num_gp,1) = i * dx + 0.5 * dx
1372                      location(num_gp,2) = (j+1) * dy
1373                      location(num_gp,3) = k * dz - 0.5 * dz
1374                      ei(num_gp)     = e(k,j+1,i+1)
1375                      dissi(num_gp)  = diss(k,j+1,i+1)
1376                      de_dxi(num_gp) = 0.0
1377                      de_dyi(num_gp) = de_dy(k,j+1,i+1)
1378                      de_dzi(num_gp) = de_dz(k,j+1,i+1)
1379                   ENDIF
1380
1381!
1382!--                If wall between gridpoint 1 and gridpoint 2, then
1383!--                Neumann boundary condition has to be applied
1384                   IF ( gp_outside_of_building(1) == 1  .AND. &
1385                        gp_outside_of_building(2) == 0 )  THEN
1386                      num_gp = num_gp + 1
1387                      location(num_gp,1) = i * dx
1388                      location(num_gp,2) = j * dy + 0.5 * dy
1389                      location(num_gp,3) = k * dz - 0.5 * dz
1390                      ei(num_gp)     = e(k,j,i)
1391                      dissi(num_gp)  = diss(k,j,i)
1392                      de_dxi(num_gp) = de_dx(k,j,i)
1393                      de_dyi(num_gp) = 0.0
1394                      de_dzi(num_gp) = de_dz(k,j,i)
1395                   ENDIF
1396
1397                   IF ( gp_outside_of_building(2) == 1  .AND. &
1398                        gp_outside_of_building(1) == 0 )  THEN
1399                      num_gp = num_gp + 1
1400                      location(num_gp,1) = i * dx
1401                      location(num_gp,2) = j * dy + 0.5 * dy
1402                      location(num_gp,3) = k * dz - 0.5 * dz
1403                      ei(num_gp)     = e(k,j+1,i)
1404                      dissi(num_gp)  = diss(k,j+1,i)
1405                      de_dxi(num_gp) = de_dx(k,j+1,i)
1406                      de_dyi(num_gp) = 0.0
1407                      de_dzi(num_gp) = de_dz(k,j+1,i)
1408                   ENDIF
1409
1410!
1411!--                If wall between gridpoint 3 and gridpoint 7, then
1412!--                Neumann boundary condition has to be applied
1413                   IF ( gp_outside_of_building(3) == 1  .AND. &
1414                        gp_outside_of_building(7) == 0 )  THEN
1415                      num_gp = num_gp + 1
1416                      location(num_gp,1) = i * dx + 0.5 * dx
1417                      location(num_gp,2) = j * dy
1418                      location(num_gp,3) = k * dz + 0.5 * dz
1419                      ei(num_gp)     = e(k+1,j,i)
1420                      dissi(num_gp)  = diss(k+1,j,i)
1421                      de_dxi(num_gp) = 0.0
1422                      de_dyi(num_gp) = de_dy(k+1,j,i)
1423                      de_dzi(num_gp) = de_dz(k+1,j,i)                     
1424                   ENDIF
1425   
1426                   IF ( gp_outside_of_building(7) == 1  .AND. &
1427                        gp_outside_of_building(3) == 0 )  THEN
1428                      num_gp = num_gp + 1
1429                      location(num_gp,1) = i * dx + 0.5 * dx
1430                      location(num_gp,2) = j * dy
1431                      location(num_gp,3) = k * dz + 0.5 * dz
1432                      ei(num_gp)     = e(k+1,j,i+1)
1433                      dissi(num_gp)  = diss(k+1,j,i+1)
1434                      de_dxi(num_gp) = 0.0
1435                      de_dyi(num_gp) = de_dy(k+1,j,i+1)
1436                      de_dzi(num_gp) = de_dz(k+1,j,i+1)
1437                   ENDIF
1438
1439!
1440!--                If wall between gridpoint 7 and gridpoint 8, then
1441!--                Neumann boundary condition has to be applied
1442                   IF ( gp_outside_of_building(7) == 1  .AND. &
1443                        gp_outside_of_building(8) == 0 )  THEN
1444                      num_gp = num_gp + 1
1445                      location(num_gp,1) = (i+1) * dx
1446                      location(num_gp,2) = j * dy + 0.5 * dy
1447                      location(num_gp,3) = k * dz + 0.5 * dz
1448                      ei(num_gp)     = e(k+1,j,i+1)
1449                      dissi(num_gp)  = diss(k+1,j,i+1)
1450                      de_dxi(num_gp) = de_dx(k+1,j,i+1)
1451                      de_dyi(num_gp) = 0.0
1452                      de_dzi(num_gp) = de_dz(k+1,j,i+1)
1453                   ENDIF
1454
1455                   IF ( gp_outside_of_building(8) == 1  .AND. &
1456                        gp_outside_of_building(7) == 0 )  THEN
1457                      num_gp = num_gp + 1
1458                      location(num_gp,1) = (i+1) * dx
1459                      location(num_gp,2) = j * dy + 0.5 * dy
1460                      location(num_gp,3) = k * dz + 0.5 * dz
1461                      ei(num_gp)     = e(k+1,j+1,i+1)
1462                      dissi(num_gp)  = diss(k+1,j+1,i+1)
1463                      de_dxi(num_gp) = de_dx(k+1,j+1,i+1)
1464                      de_dyi(num_gp) = 0.0
1465                      de_dzi(num_gp) = de_dz(k+1,j+1,i+1)
1466                   ENDIF
1467
1468!
1469!--                If wall between gridpoint 4 and gridpoint 8, then
1470!--                Neumann boundary condition has to be applied
1471                   IF ( gp_outside_of_building(4) == 1  .AND. &
1472                        gp_outside_of_building(8) == 0 )  THEN
1473                      num_gp = num_gp + 1
1474                      location(num_gp,1) = i * dx + 0.5 * dx
1475                      location(num_gp,2) = (j+1) * dy
1476                      location(num_gp,3) = k * dz + 0.5 * dz
1477                      ei(num_gp)     = e(k+1,j+1,i)
1478                      dissi(num_gp)  = diss(k+1,j+1,i)
1479                      de_dxi(num_gp) = 0.0
1480                      de_dyi(num_gp) = de_dy(k+1,j+1,i)
1481                      de_dzi(num_gp) = de_dz(k+1,j+1,i)                     
1482                   ENDIF
1483   
1484                   IF ( gp_outside_of_building(8) == 1  .AND. &
1485                        gp_outside_of_building(4) == 0 )  THEN
1486                      num_gp = num_gp + 1
1487                      location(num_gp,1) = i * dx + 0.5 * dx
1488                      location(num_gp,2) = (j+1) * dy
1489                      location(num_gp,3) = k * dz + 0.5 * dz
1490                      ei(num_gp)     = e(k+1,j+1,i+1)
1491                      dissi(num_gp)  = diss(k+1,j+1,i+1)
1492                      de_dxi(num_gp) = 0.0
1493                      de_dyi(num_gp) = de_dy(k+1,j+1,i+1)
1494                      de_dzi(num_gp) = de_dz(k+1,j+1,i+1)
1495                   ENDIF
1496
1497!
1498!--                If wall between gridpoint 3 and gridpoint 4, then
1499!--                Neumann boundary condition has to be applied
1500                   IF ( gp_outside_of_building(3) == 1  .AND. &
1501                        gp_outside_of_building(4) == 0 )  THEN
1502                      num_gp = num_gp + 1
1503                      location(num_gp,1) = i * dx
1504                      location(num_gp,2) = j * dy + 0.5 * dy
1505                      location(num_gp,3) = k * dz + 0.5 * dz
1506                      ei(num_gp)     = e(k+1,j,i)
1507                      dissi(num_gp)  = diss(k+1,j,i)
1508                      de_dxi(num_gp) = de_dx(k+1,j,i)
1509                      de_dyi(num_gp) = 0.0
1510                      de_dzi(num_gp) = de_dz(k+1,j,i)
1511                   ENDIF
1512
1513                   IF ( gp_outside_of_building(4) == 1  .AND. &
1514                        gp_outside_of_building(3) == 0 )  THEN
1515                      num_gp = num_gp + 1
1516                      location(num_gp,1) = i * dx
1517                      location(num_gp,2) = j * dy + 0.5 * dy
1518                      location(num_gp,3) = k * dz + 0.5 * dz
1519                      ei(num_gp)     = e(k+1,j+1,i)
1520                      dissi(num_gp)  = diss(k+1,j+1,i)
1521                      de_dxi(num_gp) = de_dx(k+1,j+1,i)
1522                      de_dyi(num_gp) = 0.0
1523                      de_dzi(num_gp) = de_dz(k+1,j+1,i)
1524                   ENDIF
1525
1526!
1527!--                If wall between gridpoint 1 and gridpoint 3, then
1528!--                Neumann boundary condition has to be applied
1529!--                (only one case as only building beneath is possible)
1530                   IF ( gp_outside_of_building(1) == 0  .AND. &
1531                        gp_outside_of_building(3) == 1 )  THEN
1532                      num_gp = num_gp + 1
1533                      location(num_gp,1) = i * dx
1534                      location(num_gp,2) = j * dy
1535                      location(num_gp,3) = k * dz
1536                      ei(num_gp)     = e(k+1,j,i)
1537                      dissi(num_gp)  = diss(k+1,j,i)
1538                      de_dxi(num_gp) = de_dx(k+1,j,i)
1539                      de_dyi(num_gp) = de_dy(k+1,j,i)
1540                      de_dzi(num_gp) = 0.0
1541                   ENDIF
1542 
1543!
1544!--                If wall between gridpoint 5 and gridpoint 7, then
1545!--                Neumann boundary condition has to be applied
1546!--                (only one case as only building beneath is possible)
1547                   IF ( gp_outside_of_building(5) == 0  .AND. &
1548                        gp_outside_of_building(7) == 1 )  THEN
1549                      num_gp = num_gp + 1
1550                      location(num_gp,1) = (i+1) * dx
1551                      location(num_gp,2) = j * dy
1552                      location(num_gp,3) = k * dz
1553                      ei(num_gp)     = e(k+1,j,i+1)
1554                      dissi(num_gp)  = diss(k+1,j,i+1)
1555                      de_dxi(num_gp) = de_dx(k+1,j,i+1)
1556                      de_dyi(num_gp) = de_dy(k+1,j,i+1)
1557                      de_dzi(num_gp) = 0.0
1558                   ENDIF
1559
1560!
1561!--                If wall between gridpoint 2 and gridpoint 4, then
1562!--                Neumann boundary condition has to be applied
1563!--                (only one case as only building beneath is possible)
1564                   IF ( gp_outside_of_building(2) == 0  .AND. &
1565                        gp_outside_of_building(4) == 1 )  THEN
1566                      num_gp = num_gp + 1
1567                      location(num_gp,1) = i * dx
1568                      location(num_gp,2) = (j+1) * dy
1569                      location(num_gp,3) = k * dz
1570                      ei(num_gp)     = e(k+1,j+1,i)
1571                      dissi(num_gp)  = diss(k+1,j+1,i)
1572                      de_dxi(num_gp) = de_dx(k+1,j+1,i)
1573                      de_dyi(num_gp) = de_dy(k+1,j+1,i)
1574                      de_dzi(num_gp) = 0.0
1575                   ENDIF
1576
1577!
1578!--                If wall between gridpoint 6 and gridpoint 8, then
1579!--                Neumann boundary condition has to be applied
1580!--                (only one case as only building beneath is possible)
1581                   IF ( gp_outside_of_building(6) == 0  .AND. &
1582                        gp_outside_of_building(8) == 1 )  THEN
1583                      num_gp = num_gp + 1
1584                      location(num_gp,1) = (i+1) * dx
1585                      location(num_gp,2) = (j+1) * dy
1586                      location(num_gp,3) = k * dz
1587                      ei(num_gp)     = e(k+1,j+1,i+1)
1588                      dissi(num_gp)  = diss(k+1,j+1,i+1)
1589                      de_dxi(num_gp) = de_dx(k+1,j+1,i+1)
1590                      de_dyi(num_gp) = de_dy(k+1,j+1,i+1)
1591                      de_dzi(num_gp) = 0.0
1592                   ENDIF
1593
1594!
1595!--                Carry out the interpolation
1596                   IF ( num_gp == 1 )  THEN
1597!
1598!--                   If only one of the gridpoints is situated outside of the
1599!--                   building, it follows that the values at the particle
1600!--                   location are the same as the gridpoint values
1601                      e_int     = ei(num_gp)
1602                      diss_int  = dissi(num_gp)
1603                      de_dx_int = de_dxi(num_gp)
1604                      de_dy_int = de_dyi(num_gp)
1605                      de_dz_int = de_dzi(num_gp)
1606                   ELSE IF ( num_gp > 1 )  THEN
1607
1608                      d_sum = 0.0
1609!
1610!--                   Evaluation of the distances between the gridpoints
1611!--                   contributing to the interpolated values, and the particle
1612!--                   location
1613                      DO agp = 1, num_gp
1614                         d_gp_pl(agp) = ( particles(n)%x-location(agp,1) )**2  &
1615                                      + ( particles(n)%y-location(agp,2) )**2  &
1616                                      + ( particles(n)%z-location(agp,3) )**2
1617                         d_sum        = d_sum + d_gp_pl(agp)
1618                      ENDDO
1619
1620!
1621!--                   Finally the interpolation can be carried out
1622                      e_int     = 0.0
1623                      diss_int  = 0.0
1624                      de_dx_int = 0.0
1625                      de_dy_int = 0.0
1626                      de_dz_int = 0.0
1627                      DO agp = 1, num_gp
1628                         e_int     = e_int     + ( d_sum - d_gp_pl(agp) ) * &
1629                                                ei(agp) / ( (num_gp-1) * d_sum )
1630                         diss_int  = diss_int  + ( d_sum - d_gp_pl(agp) ) * &
1631                                             dissi(agp) / ( (num_gp-1) * d_sum )
1632                         de_dx_int = de_dx_int + ( d_sum - d_gp_pl(agp) ) * &
1633                                            de_dxi(agp) / ( (num_gp-1) * d_sum )
1634                         de_dy_int = de_dy_int + ( d_sum - d_gp_pl(agp) ) * &
1635                                            de_dyi(agp) / ( (num_gp-1) * d_sum )
1636                         de_dz_int = de_dz_int + ( d_sum - d_gp_pl(agp) ) * &
1637                                            de_dzi(agp) / ( (num_gp-1) * d_sum )
1638                      ENDDO
1639
1640                   ENDIF
1641
1642                ENDIF
1643
1644             ENDIF 
1645
1646!
1647!--          Vertically interpolate the horizontally averaged SGS TKE and
1648!--          resolved-scale velocity variances and use the interpolated values
1649!--          to calculate the coefficient fs, which is a measure of the ratio
1650!--          of the subgrid-scale turbulent kinetic energy to the total amount
1651!--          of turbulent kinetic energy.
1652             IF ( k == 0 )  THEN
1653                e_mean_int = hom(0,1,8,0)
1654             ELSE
1655                e_mean_int = hom(k,1,8,0) +                                    &
1656                                           ( hom(k+1,1,8,0) - hom(k,1,8,0) ) / &
1657                                           ( zu(k+1) - zu(k) ) *               &
1658                                           ( particles(n)%z - zu(k) )
1659             ENDIF
1660
1661             kw = particles(n)%z / dz
1662
1663             IF ( k == 0 )  THEN
1664                aa  = hom(k+1,1,30,0)  * ( particles(n)%z / &
1665                                         ( 0.5 * ( zu(k+1) - zu(k) ) ) )
1666                bb  = hom(k+1,1,31,0)  * ( particles(n)%z / &
1667                                         ( 0.5 * ( zu(k+1) - zu(k) ) ) )
1668                cc  = hom(kw+1,1,32,0) * ( particles(n)%z / &
1669                                         ( 1.0 * ( zw(kw+1) - zw(kw) ) ) )
1670             ELSE
1671                aa  = hom(k,1,30,0) + ( hom(k+1,1,30,0) - hom(k,1,30,0) ) * &
1672                           ( ( particles(n)%z - zu(k) ) / ( zu(k+1) - zu(k) ) )
1673                bb  = hom(k,1,31,0) + ( hom(k+1,1,31,0) - hom(k,1,31,0) ) * &
1674                           ( ( particles(n)%z - zu(k) ) / ( zu(k+1) - zu(k) ) )
1675                cc  = hom(kw,1,32,0) + ( hom(kw+1,1,32,0)-hom(kw,1,32,0) ) *&
1676                           ( ( particles(n)%z - zw(kw) ) / ( zw(kw+1)-zw(kw) ) )
1677             ENDIF
1678
1679             vv_int = ( 1.0 / 3.0 ) * ( aa + bb + cc )
1680
1681             fs_int = ( 2.0 / 3.0 ) * e_mean_int / &
1682                         ( vv_int + ( 2.0 / 3.0 ) * e_mean_int )
1683
1684!
1685!--          Calculate the Lagrangian timescale according to the suggestion of
1686!--          Weil et al. (2004).
1687             lagr_timescale = ( 4.0 * e_int ) / &
1688                              ( 3.0 * fs_int * c_0 * diss_int )
1689
1690!
1691!--          Calculate the next particle timestep. dt_gap is the time needed to
1692!--          complete the current LES timestep.
1693             dt_gap = dt_3d - particles(n)%dt_sum
1694             dt_particle = MIN( dt_3d, 0.025 * lagr_timescale, dt_gap )
1695
1696!
1697!--          The particle timestep should not be too small in order to prevent
1698!--          the number of particle timesteps of getting too large
1699             IF ( dt_particle < dt_min_part   .AND.  dt_min_part < dt_gap ) &
1700             THEN
1701                dt_particle = dt_min_part 
1702             ENDIF
1703
1704!
1705!--          Calculate the SGS velocity components
1706             IF ( particles(n)%age == 0.0 )  THEN
1707!
1708!--             For new particles the SGS components are derived from the SGS
1709!--             TKE. Limit the Gaussian random number to the interval
1710!--             [-5.0*sigma, 5.0*sigma] in order to prevent the SGS velocities
1711!--             from becoming unrealistically large.
1712                particles(n)%speed_x_sgs = SQRT( 2.0 * sgs_wfu_part * e_int ) *&
1713                                           ( random_gauss( iran_part, 5.0 )    &
1714                                             - 1.0 )
1715                particles(n)%speed_y_sgs = SQRT( 2.0 * sgs_wfv_part * e_int ) *&
1716                                           ( random_gauss( iran_part, 5.0 )    &
1717                                             - 1.0 )
1718                particles(n)%speed_z_sgs = SQRT( 2.0 * sgs_wfw_part * e_int ) *&
1719                                           ( random_gauss( iran_part, 5.0 )    &
1720                                             - 1.0 )
1721
1722             ELSE
1723
1724!
1725!--             Restriction of the size of the new timestep: compared to the
1726!--             previous timestep the increase must not exceed 200%
1727
1728                dt_particle_m = particles(n)%age - particles(n)%age_m
1729                IF ( dt_particle > 2.0 * dt_particle_m )  THEN
1730                   dt_particle = 2.0 * dt_particle_m
1731                ENDIF
1732
1733!
1734!--             For old particles the SGS components are correlated with the
1735!--             values from the previous timestep. Random numbers have also to
1736!--             be limited (see above).
1737!--             As negative values for the subgrid TKE are not allowed, the
1738!--             change of the subgrid TKE with time cannot be smaller than
1739!--             -e_int/dt_particle. This value is used as a lower boundary
1740!--             value for the change of TKE
1741
1742                de_dt_min = - e_int / dt_particle
1743
1744                de_dt = ( e_int - particles(n)%e_m ) / dt_particle_m
1745
1746                IF ( de_dt < de_dt_min )  THEN
1747                   de_dt = de_dt_min
1748                ENDIF
1749
1750                particles(n)%speed_x_sgs = particles(n)%speed_x_sgs -          &
1751                       fs_int * c_0 * diss_int * particles(n)%speed_x_sgs *    &
1752                       dt_particle / ( 4.0 * sgs_wfu_part * e_int ) +          &
1753                       ( 2.0 * sgs_wfu_part * de_dt *                          &
1754                               particles(n)%speed_x_sgs /                      &
1755                         ( 2.0 * sgs_wfu_part * e_int ) + de_dx_int            &
1756                       ) * dt_particle / 2.0                        +          &
1757                       SQRT( fs_int * c_0 * diss_int ) *                       &
1758                       ( random_gauss( iran_part, 5.0 ) - 1.0 ) *              &
1759                       SQRT( dt_particle )
1760
1761                particles(n)%speed_y_sgs = particles(n)%speed_y_sgs -          &
1762                       fs_int * c_0 * diss_int * particles(n)%speed_y_sgs *    &
1763                       dt_particle / ( 4.0 * sgs_wfv_part * e_int ) +          &
1764                       ( 2.0 * sgs_wfv_part * de_dt *                          &
1765                               particles(n)%speed_y_sgs /                      &
1766                         ( 2.0 * sgs_wfv_part * e_int ) + de_dy_int            &
1767                       ) * dt_particle / 2.0                        +          &
1768                       SQRT( fs_int * c_0 * diss_int ) *                       &
1769                       ( random_gauss( iran_part, 5.0 ) - 1.0 ) *              &
1770                       SQRT( dt_particle )
1771
1772                particles(n)%speed_z_sgs = particles(n)%speed_z_sgs -          &
1773                       fs_int * c_0 * diss_int * particles(n)%speed_z_sgs *    &
1774                       dt_particle / ( 4.0 * sgs_wfw_part * e_int ) +          &
1775                       ( 2.0 * sgs_wfw_part * de_dt *                          &
1776                               particles(n)%speed_z_sgs /                      &
1777                         ( 2.0 * sgs_wfw_part * e_int ) + de_dz_int            &
1778                       ) * dt_particle / 2.0                        +          &
1779                       SQRT( fs_int * c_0 * diss_int ) *                       &
1780                       ( random_gauss( iran_part, 5.0 ) - 1.0 ) *              &
1781                       SQRT( dt_particle )
1782
1783             ENDIF
1784
1785             u_int = u_int + particles(n)%speed_x_sgs
1786             v_int = v_int + particles(n)%speed_y_sgs
1787             w_int = w_int + particles(n)%speed_z_sgs
1788
1789!
1790!--          Store the SGS TKE of the current timelevel which is needed for
1791!--          for calculating the SGS particle velocities at the next timestep
1792             particles(n)%e_m = e_int
1793
1794          ELSE
1795!
1796!--          If no SGS velocities are used, only the particle timestep has to
1797!--          be set
1798             dt_particle = dt_3d
1799
1800          ENDIF
1801
1802!
1803!--       Remember the old age of the particle ( needed to prevent that a
1804!--       particle crosses several PEs during one timestep and for the
1805!--       evaluation of the subgrid particle velocity fluctuations )
1806          particles(n)%age_m = particles(n)%age
1807
1808
1809!
1810!--       Particle advection
1811          IF ( particle_groups(particles(n)%group)%density_ratio == 0.0 )  THEN
1812!
1813!--          Pure passive transport (without particle inertia)
1814             particles(n)%x = particles(n)%x + u_int * dt_particle
1815             particles(n)%y = particles(n)%y + v_int * dt_particle
1816             particles(n)%z = particles(n)%z + w_int * dt_particle
1817
1818             particles(n)%speed_x = u_int
1819             particles(n)%speed_y = v_int
1820             particles(n)%speed_z = w_int
1821
1822          ELSE
1823!
1824!--          Transport of particles with inertia
1825             particles(n)%x = particles(n)%x + particles(n)%speed_x * &
1826                                               dt_particle
1827             particles(n)%y = particles(n)%y + particles(n)%speed_y * &
1828                                               dt_particle
1829             particles(n)%z = particles(n)%z + particles(n)%speed_z * &
1830                                               dt_particle
1831
1832!
1833!--          Update of the particle velocity
1834             dens_ratio = particle_groups(particles(n)%group)%density_ratio
1835             IF ( cloud_droplets )  THEN
1836                exp_arg  = 4.5 * dens_ratio * molecular_viscosity /        &
1837                           ( particles(n)%radius )**2 /                    &
1838                           ( 1.0 + 0.15 * ( 2.0 * particles(n)%radius *    &
1839                             SQRT( ( u_int - particles(n)%speed_x )**2 +   &
1840                                   ( v_int - particles(n)%speed_y )**2 +   &
1841                                   ( w_int - particles(n)%speed_z )**2 ) / &
1842                                            molecular_viscosity )**0.687   &
1843                           )
1844                exp_term = EXP( -exp_arg * dt_particle )
1845             ELSEIF ( use_sgs_for_particles )  THEN
1846                exp_arg  = particle_groups(particles(n)%group)%exp_arg
1847                exp_term = EXP( -exp_arg * dt_particle )
1848             ELSE
1849                exp_arg  = particle_groups(particles(n)%group)%exp_arg
1850                exp_term = particle_groups(particles(n)%group)%exp_term
1851             ENDIF
1852             particles(n)%speed_x = particles(n)%speed_x * exp_term + &
1853                                    u_int * ( 1.0 - exp_term )
1854              particles(n)%speed_y = particles(n)%speed_y * exp_term + &
1855                                    v_int * ( 1.0 - exp_term )
1856              particles(n)%speed_z = particles(n)%speed_z * exp_term +       &
1857                              ( w_int - ( 1.0 - dens_ratio ) * g / exp_arg ) &
1858                                    * ( 1.0 - exp_term )
1859          ENDIF
1860
1861!
1862!--       Increment the particle age and the total time that the particle
1863!--       has advanced within the particle timestep procedure
1864          particles(n)%age    = particles(n)%age    + dt_particle
1865          particles(n)%dt_sum = particles(n)%dt_sum + dt_particle
1866
1867!
1868!--       Check whether there is still a particle that has not yet completed
1869!--       the total LES timestep
1870          IF ( ( dt_3d - particles(n)%dt_sum ) > 1E-8 )  THEN
1871             dt_3d_reached_l = .FALSE.
1872          ENDIF
1873
1874       ENDDO   ! advection loop
1875
1876!
1877!--    Particle reflection from walls
1878       CALL particle_boundary_conds
1879
1880!
1881!--    User-defined actions after the calculation of the new particle position
1882       CALL user_advec_particles
1883
1884!
1885!--    Find out, if all particles on every PE have completed the LES timestep
1886!--    and set the switch corespondingly
1887#if defined( __parallel )
1888       CALL MPI_ALLREDUCE( dt_3d_reached_l, dt_3d_reached, 1, MPI_LOGICAL, &
1889                           MPI_LAND, comm2d, ierr )
1890#else
1891       dt_3d_reached = dt_3d_reached_l
1892#endif     
1893
1894       CALL cpu_log( log_point_s(44), 'advec_part_advec', 'stop' )
1895
1896!
1897!--    Increment time since last release
1898       IF ( dt_3d_reached )  time_prel = time_prel + dt_3d
1899
1900!    WRITE ( 9, * ) '*** advec_particles: ##0.4'
1901!    CALL local_flush( 9 )
1902!    nd = 0
1903!    DO  n = 1, number_of_particles
1904!       IF ( .NOT. particle_mask(n) )  nd = nd + 1
1905!    ENDDO
1906!    IF ( nd /= deleted_particles ) THEN
1907!       WRITE (9,*) '*** nd=',nd,' deleted_particles=',deleted_particles
1908!       CALL local_flush( 9 )
1909!       CALL MPI_ABORT( comm2d, 9999, ierr )
1910!    ENDIF
1911
1912!
1913!--    If necessary, release new set of particles
1914       IF ( time_prel >= dt_prel  .AND.  end_time_prel > simulated_time  .AND. &
1915            dt_3d_reached )  THEN
1916
1917!
1918!--       Check, if particle storage must be extended
1919          IF ( number_of_particles + number_of_initial_particles > &
1920               maximum_number_of_particles  )  THEN
1921             IF ( netcdf_output )  THEN
1922                message_string = 'maximum_number_of_particles ' // &
1923                                 'needs to be increased ' // &
1924                                 '&but this is not allowed with ' // &
1925                                 'NetCDF output switched on'
1926                CALL message( 'advec_particles', 'PA0146', 2, 2, 0, 6, 0 )
1927             ELSE
1928!    WRITE ( 9, * ) '*** advec_particles: before allocate_prt_memory dt_prel'
1929!    CALL local_flush( 9 )
1930                CALL allocate_prt_memory( number_of_initial_particles )
1931!    WRITE ( 9, * ) '*** advec_particles: after allocate_prt_memory dt_prel'
1932!    CALL local_flush( 9 )
1933             ENDIF
1934          ENDIF
1935
1936!
1937!--       Check, if tail storage must be extended
1938          IF ( use_particle_tails )  THEN
1939             IF ( number_of_tails + number_of_initial_tails > &
1940                  maximum_number_of_tails  )  THEN
1941                IF ( netcdf_output )  THEN
1942                   message_string = 'maximum_number_of_tails ' // &
1943                                    'needs to be increased ' // &
1944                                    '&but this is not allowed wi' // &
1945                                    'th NetCDF output switched on'
1946                   CALL message( 'advec_particles', 'PA0147', 2, 2, 0, 6, 0 )
1947                ELSE
1948!    WRITE ( 9, * ) '*** advec_particles: before allocate_tail_memory dt_prel'
1949!    CALL local_flush( 9 )
1950                   CALL allocate_tail_memory( number_of_initial_tails )
1951!    WRITE ( 9, * ) '*** advec_particles: after allocate_tail_memory dt_prel'
1952!    CALL local_flush( 9 )
1953                ENDIF
1954             ENDIF
1955          ENDIF
1956
1957!
1958!--       The MOD function allows for changes in the output interval with
1959!--       restart runs.
1960          time_prel = MOD( time_prel, MAX( dt_prel, dt_3d ) )
1961          IF ( number_of_initial_particles /= 0 )  THEN
1962             is = number_of_particles+1
1963             ie = number_of_particles+number_of_initial_particles
1964             particles(is:ie) = initial_particles(1:number_of_initial_particles)
1965!
1966!--          Add random fluctuation to particle positions. Particles should
1967!--          remain in the subdomain.
1968             IF ( random_start_position )  THEN
1969                DO  n = is, ie
1970                   IF ( psl(particles(n)%group) /= psr(particles(n)%group) ) &
1971                   THEN
1972                      particles(n)%x = particles(n)%x + &
1973                                       ( random_function( iran_part ) - 0.5 ) *&
1974                                       pdx(particles(n)%group)
1975                      IF ( particles(n)%x  <=  ( nxl - 0.5 ) * dx )  THEN
1976                         particles(n)%x = ( nxl - 0.4999999999 ) * dx
1977                      ELSEIF ( particles(n)%x  >=  ( nxr + 0.5 ) * dx )  THEN
1978                         particles(n)%x = ( nxr + 0.4999999999 ) * dx
1979                      ENDIF
1980                   ENDIF
1981                   IF ( pss(particles(n)%group) /= psn(particles(n)%group) ) &
1982                   THEN
1983                      particles(n)%y = particles(n)%y + &
1984                                       ( random_function( iran_part ) - 0.5 ) *&
1985                                       pdy(particles(n)%group)
1986                      IF ( particles(n)%y  <=  ( nys - 0.5 ) * dy )  THEN
1987                         particles(n)%y = ( nys - 0.4999999999 ) * dy
1988                      ELSEIF ( particles(n)%y  >=  ( nyn + 0.5 ) * dy )  THEN
1989                         particles(n)%y = ( nyn + 0.4999999999 ) * dy
1990                      ENDIF
1991                   ENDIF
1992                   IF ( psb(particles(n)%group) /= pst(particles(n)%group) ) &
1993                   THEN
1994                      particles(n)%z = particles(n)%z + &
1995                                       ( random_function( iran_part ) - 0.5 ) *&
1996                                       pdz(particles(n)%group)
1997                   ENDIF
1998                ENDDO
1999             ENDIF
2000
2001!
2002!--          Set the beginning of the new particle tails and their age
2003             IF ( use_particle_tails )  THEN
2004                DO  n = is, ie
2005!
2006!--                New particles which should have a tail, already have got a
2007!--                provisional tail id unequal zero (see init_particles)
2008                   IF ( particles(n)%tail_id /= 0 )  THEN
2009                      number_of_tails = number_of_tails + 1
2010                      nn = number_of_tails
2011                      particles(n)%tail_id = nn   ! set the final tail id
2012                      particle_tail_coordinates(1,1,nn) = particles(n)%x
2013                      particle_tail_coordinates(1,2,nn) = particles(n)%y
2014                      particle_tail_coordinates(1,3,nn) = particles(n)%z
2015                      particle_tail_coordinates(1,4,nn) = particles(n)%color
2016                      particles(n)%tailpoints = 1
2017                      IF ( minimum_tailpoint_distance /= 0.0 )  THEN
2018                         particle_tail_coordinates(2,1,nn) = particles(n)%x
2019                         particle_tail_coordinates(2,2,nn) = particles(n)%y
2020                         particle_tail_coordinates(2,3,nn) = particles(n)%z
2021                         particle_tail_coordinates(2,4,nn) = particles(n)%color
2022                         particle_tail_coordinates(1:2,5,nn) = 0.0
2023                         particles(n)%tailpoints = 2
2024                      ENDIF
2025                   ENDIF
2026                ENDDO
2027             ENDIF
2028!    WRITE ( 9, * ) '*** advec_particles: after setting the beginning of new tails'
2029!    CALL local_flush( 9 )
2030
2031             number_of_particles = number_of_particles + &
2032                                   number_of_initial_particles
2033          ENDIF
2034
2035       ENDIF
2036
2037!    WRITE ( 9, * ) '*** advec_particles: ##0.5'
2038!    CALL local_flush( 9 )
2039!    nd = 0
2040!    DO  n = 1, number_of_particles
2041!       IF ( .NOT. particle_mask(n) )  nd = nd + 1
2042!    ENDDO
2043!    IF ( nd /= deleted_particles ) THEN
2044!       WRITE (9,*) '*** nd=',nd,' deleted_particles=',deleted_particles
2045!       CALL local_flush( 9 )
2046!       CALL MPI_ABORT( comm2d, 9999, ierr )
2047!    ENDIF
2048
2049!    IF ( number_of_particles /= number_of_tails )  THEN
2050!       WRITE (9,*) '--- advec_particles: #2'
2051!       WRITE (9,*) '    #of p=',number_of_particles,' #of t=',number_of_tails
2052!       CALL local_flush( 9 )
2053!    ENDIF
2054!    DO  n = 1, number_of_particles
2055!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
2056!       THEN
2057!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
2058!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
2059!          CALL local_flush( 9 )
2060!          CALL MPI_ABORT( comm2d, 9999, ierr )
2061!       ENDIF
2062!    ENDDO
2063
2064#if defined( __parallel )
2065!
2066!--    As soon as one particle has moved beyond the boundary of the domain, it
2067!--    is included in the relevant transfer arrays and marked for subsequent
2068!--    deletion on this PE.
2069!--    First run for crossings in x direction. Find out first the number of
2070!--    particles to be transferred and allocate temporary arrays needed to store
2071!--    them.
2072!--    For a one-dimensional decomposition along y, no transfer is necessary,
2073!--    because the particle remains on the PE.
2074       trlp_count  = 0
2075       trlpt_count = 0
2076       trrp_count  = 0
2077       trrpt_count = 0
2078       IF ( pdims(1) /= 1 )  THEN
2079!
2080!--       First calculate the storage necessary for sending and receiving the
2081!--       data
2082          DO  n = 1, number_of_particles
2083             i = ( particles(n)%x + 0.5 * dx ) * ddx
2084!
2085!--          Above calculation does not work for indices less than zero
2086             IF ( particles(n)%x < -0.5 * dx )  i = -1
2087
2088             IF ( i < nxl )  THEN
2089                trlp_count = trlp_count + 1
2090                IF ( particles(n)%tail_id /= 0 )  trlpt_count = trlpt_count + 1
2091             ELSEIF ( i > nxr )  THEN
2092                trrp_count = trrp_count + 1
2093                IF ( particles(n)%tail_id /= 0 )  trrpt_count = trrpt_count + 1
2094             ENDIF
2095          ENDDO
2096          IF ( trlp_count  == 0 )  trlp_count  = 1
2097          IF ( trlpt_count == 0 )  trlpt_count = 1
2098          IF ( trrp_count  == 0 )  trrp_count  = 1
2099          IF ( trrpt_count == 0 )  trrpt_count = 1
2100
2101          ALLOCATE( trlp(trlp_count), trrp(trrp_count) )
2102
2103          trlp = particle_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
2104                                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
2105                                0.0, 0, 0, 0, 0 )
2106          trrp = particle_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
2107                                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
2108                                0.0, 0, 0, 0, 0 )
2109
2110          IF ( use_particle_tails )  THEN
2111             ALLOCATE( trlpt(maximum_number_of_tailpoints,5,trlpt_count), &
2112                       trrpt(maximum_number_of_tailpoints,5,trrpt_count) )
2113             tlength = maximum_number_of_tailpoints * 5
2114          ENDIF
2115
2116          trlp_count  = 0
2117          trlpt_count = 0
2118          trrp_count  = 0
2119          trrpt_count = 0
2120
2121       ENDIF
2122
2123!    WRITE ( 9, * ) '*** advec_particles: ##1'
2124!    CALL local_flush( 9 )
2125!    nd = 0
2126!    DO  n = 1, number_of_particles
2127!       IF ( .NOT. particle_mask(n) )  nd = nd + 1
2128!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
2129!       THEN
2130!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
2131!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
2132!          CALL local_flush( 9 )
2133!          CALL MPI_ABORT( comm2d, 9999, ierr )
2134!       ENDIF
2135!    ENDDO
2136!    IF ( nd /= deleted_particles ) THEN
2137!       WRITE (9,*) '*** nd=',nd,' deleted_particles=',deleted_particles
2138!       CALL local_flush( 9 )
2139!       CALL MPI_ABORT( comm2d, 9999, ierr )
2140!    ENDIF
2141
2142       DO  n = 1, number_of_particles
2143
2144          nn = particles(n)%tail_id
2145
2146          i = ( particles(n)%x + 0.5 * dx ) * ddx
2147!
2148!--       Above calculation does not work for indices less than zero
2149          IF ( particles(n)%x < - 0.5 * dx )  i = -1
2150
2151          IF ( i <  nxl )  THEN
2152             IF ( i < 0 )  THEN
2153!
2154!--             Apply boundary condition along x
2155                IF ( ibc_par_lr == 0 )  THEN
2156!
2157!--                Cyclic condition
2158                   IF ( pdims(1) == 1 )  THEN
2159                      particles(n)%x        = ( nx + 1 ) * dx + particles(n)%x
2160                      particles(n)%origin_x = ( nx + 1 ) * dx + &
2161                                              particles(n)%origin_x
2162                      IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2163                         i  = particles(n)%tailpoints
2164                         particle_tail_coordinates(1:i,1,nn) = ( nx + 1 ) * dx &
2165                                           + particle_tail_coordinates(1:i,1,nn)
2166                      ENDIF
2167                   ELSE
2168                      trlp_count = trlp_count + 1
2169                      trlp(trlp_count) = particles(n)
2170                      trlp(trlp_count)%x = ( nx + 1 ) * dx + trlp(trlp_count)%x
2171                      trlp(trlp_count)%origin_x = trlp(trlp_count)%origin_x + &
2172                                                  ( nx + 1 ) * dx
2173                      particle_mask(n)  = .FALSE.
2174                      deleted_particles = deleted_particles + 1
2175
2176                      IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2177                         trlpt_count = trlpt_count + 1
2178                         trlpt(:,:,trlpt_count) = &
2179                                               particle_tail_coordinates(:,:,nn)
2180                         trlpt(:,1,trlpt_count) = ( nx + 1 ) * dx + &
2181                                                  trlpt(:,1,trlpt_count)
2182                         tail_mask(nn) = .FALSE.
2183                         deleted_tails = deleted_tails + 1
2184                      ENDIF
2185                   ENDIF
2186
2187                ELSEIF ( ibc_par_lr == 1 )  THEN
2188!
2189!--                Particle absorption
2190                   particle_mask(n) = .FALSE.
2191                   deleted_particles = deleted_particles + 1
2192                   IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2193                      tail_mask(nn) = .FALSE.
2194                      deleted_tails = deleted_tails + 1
2195                   ENDIF
2196
2197                ELSEIF ( ibc_par_lr == 2 )  THEN
2198!
2199!--                Particle reflection
2200                   particles(n)%x       = -particles(n)%x
2201                   particles(n)%speed_x = -particles(n)%speed_x
2202
2203                ENDIF
2204             ELSE
2205!
2206!--             Store particle data in the transfer array, which will be send
2207!--             to the neighbouring PE
2208                trlp_count = trlp_count + 1
2209                trlp(trlp_count) = particles(n)
2210                particle_mask(n) = .FALSE.
2211                deleted_particles = deleted_particles + 1
2212
2213                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2214                   trlpt_count = trlpt_count + 1
2215                   trlpt(:,:,trlpt_count) = particle_tail_coordinates(:,:,nn)
2216                   tail_mask(nn) = .FALSE.
2217                   deleted_tails = deleted_tails + 1
2218                ENDIF
2219            ENDIF
2220
2221          ELSEIF ( i > nxr )  THEN
2222             IF ( i > nx )  THEN
2223!
2224!--             Apply boundary condition along x
2225                IF ( ibc_par_lr == 0 )  THEN
2226!
2227!--                Cyclic condition
2228                   IF ( pdims(1) == 1 )  THEN
2229                      particles(n)%x = particles(n)%x - ( nx + 1 ) * dx
2230                      particles(n)%origin_x = particles(n)%origin_x - &
2231                                              ( nx + 1 ) * dx
2232                      IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2233                         i = particles(n)%tailpoints
2234                         particle_tail_coordinates(1:i,1,nn) = - ( nx+1 ) * dx &
2235                                           + particle_tail_coordinates(1:i,1,nn)
2236                      ENDIF
2237                   ELSE
2238                      trrp_count = trrp_count + 1
2239                      trrp(trrp_count) = particles(n)
2240                      trrp(trrp_count)%x = trrp(trrp_count)%x - ( nx + 1 ) * dx
2241                      trrp(trrp_count)%origin_x = trrp(trrp_count)%origin_x - &
2242                                                  ( nx + 1 ) * dx
2243                      particle_mask(n) = .FALSE.
2244                      deleted_particles = deleted_particles + 1
2245
2246                      IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2247                         trrpt_count = trrpt_count + 1
2248                         trrpt(:,:,trrpt_count) = &
2249                                               particle_tail_coordinates(:,:,nn)
2250                         trrpt(:,1,trrpt_count) = trrpt(:,1,trrpt_count) - &
2251                                                  ( nx + 1 ) * dx
2252                         tail_mask(nn) = .FALSE.
2253                         deleted_tails = deleted_tails + 1
2254                      ENDIF
2255                   ENDIF
2256
2257                ELSEIF ( ibc_par_lr == 1 )  THEN
2258!
2259!--                Particle absorption
2260                   particle_mask(n) = .FALSE.
2261                   deleted_particles = deleted_particles + 1
2262                   IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2263                      tail_mask(nn) = .FALSE.
2264                      deleted_tails = deleted_tails + 1
2265                   ENDIF
2266
2267                ELSEIF ( ibc_par_lr == 2 )  THEN
2268!
2269!--                Particle reflection
2270                   particles(n)%x       = 2 * ( nx * dx ) - particles(n)%x
2271                   particles(n)%speed_x = -particles(n)%speed_x
2272
2273                ENDIF
2274             ELSE
2275!
2276!--             Store particle data in the transfer array, which will be send
2277!--             to the neighbouring PE
2278                trrp_count = trrp_count + 1
2279                trrp(trrp_count) = particles(n)
2280                particle_mask(n) = .FALSE.
2281                deleted_particles = deleted_particles + 1
2282
2283                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2284                   trrpt_count = trrpt_count + 1
2285                   trrpt(:,:,trrpt_count) = particle_tail_coordinates(:,:,nn)
2286                   tail_mask(nn) = .FALSE.
2287                   deleted_tails = deleted_tails + 1
2288                ENDIF
2289             ENDIF
2290
2291          ENDIF
2292       ENDDO
2293
2294!    WRITE ( 9, * ) '*** advec_particles: ##2'
2295!    CALL local_flush( 9 )
2296!    nd = 0
2297!    DO  n = 1, number_of_particles
2298!       IF ( .NOT. particle_mask(n) )  nd = nd + 1
2299!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
2300!       THEN
2301!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
2302!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
2303!          CALL local_flush( 9 )
2304!          CALL MPI_ABORT( comm2d, 9999, ierr )
2305!       ENDIF
2306!    ENDDO
2307!    IF ( nd /= deleted_particles ) THEN
2308!       WRITE (9,*) '*** nd=',nd,' deleted_particles=',deleted_particles
2309!       CALL local_flush( 9 )
2310!       CALL MPI_ABORT( comm2d, 9999, ierr )
2311!    ENDIF
2312
2313!
2314!--    Send left boundary, receive right boundary (but first exchange how many
2315!--    and check, if particle storage must be extended)
2316       IF ( pdims(1) /= 1 )  THEN
2317
2318          CALL cpu_log( log_point_s(23), 'sendrcv_particles', 'start' )
2319          CALL MPI_SENDRECV( trlp_count,      1, MPI_INTEGER, pleft,  0, &
2320                             trrp_count_recv, 1, MPI_INTEGER, pright, 0, &
2321                             comm2d, status, ierr )
2322
2323          IF ( number_of_particles + trrp_count_recv > &
2324               maximum_number_of_particles )           &
2325          THEN
2326             IF ( netcdf_output )  THEN
2327                 message_string = 'maximum_number_of_particles ' // &
2328                                  'needs to be increased ' // &
2329                                  '&but this is not allowed with ' //  &
2330                                  'NetCDF output switched on'
2331                CALL message( 'advec_particles', 'PA0146', 2, 2, 0, 6, 0 )
2332             ELSE
2333!    WRITE ( 9, * ) '*** advec_particles: before allocate_prt_memory trrp'
2334!    CALL local_flush( 9 )
2335                CALL allocate_prt_memory( trrp_count_recv )
2336!    WRITE ( 9, * ) '*** advec_particles: after allocate_prt_memory trrp'
2337!    CALL local_flush( 9 )
2338             ENDIF
2339          ENDIF
2340
2341          CALL MPI_SENDRECV( trlp(1)%age, trlp_count, mpi_particle_type,     &
2342                             pleft, 1, particles(number_of_particles+1)%age, &
2343                             trrp_count_recv, mpi_particle_type, pright, 1,  &
2344                             comm2d, status, ierr )
2345
2346          IF ( use_particle_tails )  THEN
2347
2348             CALL MPI_SENDRECV( trlpt_count,      1, MPI_INTEGER, pleft,  0, &
2349                                trrpt_count_recv, 1, MPI_INTEGER, pright, 0, &
2350                                comm2d, status, ierr )
2351
2352             IF ( number_of_tails+trrpt_count_recv > maximum_number_of_tails ) &
2353             THEN
2354                IF ( netcdf_output )  THEN
2355                   message_string = 'maximum_number_of_tails ' // &
2356                                    'needs to be increased ' // &
2357                                    '&but this is not allowed wi'// &
2358                                    'th NetCDF output switched on'
2359                CALL message( 'advec_particles', 'PA0147', 2, 2, 0, 6, 0 )
2360                ELSE
2361!    WRITE ( 9, * ) '*** advec_particles: before allocate_tail_memory trrpt'
2362!    CALL local_flush( 9 )
2363                   CALL allocate_tail_memory( trrpt_count_recv )
2364!    WRITE ( 9, * ) '*** advec_particles: after allocate_tail_memory trrpt'
2365!    CALL local_flush( 9 )
2366                ENDIF
2367             ENDIF
2368
2369             CALL MPI_SENDRECV( trlpt(1,1,1), trlpt_count*tlength, MPI_REAL,   &
2370                                pleft, 1,                                      &
2371                             particle_tail_coordinates(1,1,number_of_tails+1), &
2372                                trrpt_count_recv*tlength, MPI_REAL, pright, 1, &
2373                                comm2d, status, ierr )
2374!
2375!--          Update the tail ids for the transferred particles
2376             nn = number_of_tails
2377             DO  n = number_of_particles+1, number_of_particles+trrp_count_recv
2378                IF ( particles(n)%tail_id /= 0 )  THEN
2379                   nn = nn + 1
2380                   particles(n)%tail_id = nn
2381                ENDIF
2382             ENDDO
2383
2384          ENDIF
2385
2386          number_of_particles = number_of_particles + trrp_count_recv
2387          number_of_tails     = number_of_tails     + trrpt_count_recv
2388!       IF ( number_of_particles /= number_of_tails )  THEN
2389!          WRITE (9,*) '--- advec_particles: #3'
2390!          WRITE (9,*) '    #of p=',number_of_particles,' #of t=',number_of_tails
2391!          CALL local_flush( 9 )
2392!       ENDIF
2393
2394!
2395!--       Send right boundary, receive left boundary
2396          CALL MPI_SENDRECV( trrp_count,      1, MPI_INTEGER, pright, 0, &
2397                             trlp_count_recv, 1, MPI_INTEGER, pleft,  0, &
2398                             comm2d, status, ierr )
2399
2400          IF ( number_of_particles + trlp_count_recv > &
2401               maximum_number_of_particles )           &
2402          THEN
2403             IF ( netcdf_output )  THEN
2404                message_string = 'maximum_number_of_particles ' // &
2405                                 'needs to be increased ' // &
2406                                 '&but this is not allowed with '// &
2407                                 'NetCDF output switched on'
2408                CALL message( 'advec_particles', 'PA0146', 2, 2, 0, 6, 0 )
2409             ELSE
2410!    WRITE ( 9, * ) '*** advec_particles: before allocate_prt_memory trlp'
2411!    CALL local_flush( 9 )
2412                CALL allocate_prt_memory( trlp_count_recv )
2413!    WRITE ( 9, * ) '*** advec_particles: after allocate_prt_memory trlp'
2414!    CALL local_flush( 9 )
2415             ENDIF
2416          ENDIF
2417
2418          CALL MPI_SENDRECV( trrp(1)%age, trrp_count, mpi_particle_type,      &
2419                             pright, 1, particles(number_of_particles+1)%age, &
2420                             trlp_count_recv, mpi_particle_type, pleft, 1,    &
2421                             comm2d, status, ierr )
2422
2423          IF ( use_particle_tails )  THEN
2424
2425             CALL MPI_SENDRECV( trrpt_count,      1, MPI_INTEGER, pright, 0, &
2426                                trlpt_count_recv, 1, MPI_INTEGER, pleft,  0, &
2427                                comm2d, status, ierr )
2428
2429             IF ( number_of_tails+trlpt_count_recv > maximum_number_of_tails ) &
2430             THEN
2431                IF ( netcdf_output )  THEN
2432                   message_string = 'maximum_number_of_tails ' // &
2433                                    'needs to be increased ' // &
2434                                    '&but this is not allowed wi'// &
2435                                    'th NetCDF output switched on'
2436                   CALL message( 'advec_particles', 'PA0147', 2, 2, 0, 6, 0 ) 
2437                ELSE
2438!    WRITE ( 9, * ) '*** advec_particles: before allocate_tail_memory trlpt'
2439!    CALL local_flush( 9 )
2440                   CALL allocate_tail_memory( trlpt_count_recv )
2441!    WRITE ( 9, * ) '*** advec_particles: after allocate_tail_memory trlpt'
2442!    CALL local_flush( 9 )
2443                ENDIF
2444             ENDIF
2445
2446             CALL MPI_SENDRECV( trrpt(1,1,1), trrpt_count*tlength, MPI_REAL,   &
2447                                pright, 1,                                     &
2448                             particle_tail_coordinates(1,1,number_of_tails+1), &
2449                                trlpt_count_recv*tlength, MPI_REAL, pleft, 1,  &
2450                                comm2d, status, ierr )
2451!
2452!--          Update the tail ids for the transferred particles
2453             nn = number_of_tails
2454             DO  n = number_of_particles+1, number_of_particles+trlp_count_recv
2455                IF ( particles(n)%tail_id /= 0 )  THEN
2456                   nn = nn + 1
2457                   particles(n)%tail_id = nn
2458                ENDIF
2459             ENDDO
2460
2461          ENDIF
2462
2463          number_of_particles = number_of_particles + trlp_count_recv
2464          number_of_tails     = number_of_tails     + trlpt_count_recv
2465!       IF ( number_of_particles /= number_of_tails )  THEN
2466!          WRITE (9,*) '--- advec_particles: #4'
2467!          WRITE (9,*) '    #of p=',number_of_particles,' #of t=',number_of_tails
2468!          CALL local_flush( 9 )
2469!       ENDIF
2470
2471          IF ( use_particle_tails )  THEN
2472             DEALLOCATE( trlpt, trrpt )
2473          ENDIF
2474          DEALLOCATE( trlp, trrp ) 
2475
2476          CALL cpu_log( log_point_s(23), 'sendrcv_particles', 'pause' )
2477
2478       ENDIF
2479
2480!    WRITE ( 9, * ) '*** advec_particles: ##3'
2481!    CALL local_flush( 9 )
2482!    nd = 0
2483!    DO  n = 1, number_of_particles
2484!       IF ( .NOT. particle_mask(n) )  nd = nd + 1
2485!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
2486!       THEN
2487!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
2488!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
2489!          CALL local_flush( 9 )
2490!          CALL MPI_ABORT( comm2d, 9999, ierr )
2491!       ENDIF
2492!    ENDDO
2493!    IF ( nd /= deleted_particles ) THEN
2494!       WRITE (9,*) '*** nd=',nd,' deleted_particles=',deleted_particles
2495!       CALL local_flush( 9 )
2496!       CALL MPI_ABORT( comm2d, 9999, ierr )
2497!    ENDIF
2498
2499!
2500!--    Check whether particles have crossed the boundaries in y direction. Note
2501!--    that this case can also apply to particles that have just been received
2502!--    from the adjacent right or left PE.
2503!--    Find out first the number of particles to be transferred and allocate
2504!--    temporary arrays needed to store them.
2505!--    For a one-dimensional decomposition along x, no transfer is necessary,
2506!--    because the particle remains on the PE.
2507       trsp_count  = 0
2508       trspt_count = 0
2509       trnp_count  = 0
2510       trnpt_count = 0
2511       IF ( pdims(2) /= 1 )  THEN
2512!
2513!--       First calculate the storage necessary for sending and receiving the
2514!--       data
2515          DO  n = 1, number_of_particles
2516             IF ( particle_mask(n) )  THEN
2517                j = ( particles(n)%y + 0.5 * dy ) * ddy
2518!
2519!--             Above calculation does not work for indices less than zero
2520                IF ( particles(n)%y < -0.5 * dy )  j = -1
2521
2522                IF ( j < nys )  THEN
2523                   trsp_count = trsp_count + 1
2524                   IF ( particles(n)%tail_id /= 0 )  trspt_count = trspt_count+1
2525                ELSEIF ( j > nyn )  THEN
2526                   trnp_count = trnp_count + 1
2527                   IF ( particles(n)%tail_id /= 0 )  trnpt_count = trnpt_count+1
2528                ENDIF
2529             ENDIF
2530          ENDDO
2531          IF ( trsp_count  == 0 )  trsp_count  = 1
2532          IF ( trspt_count == 0 )  trspt_count = 1
2533          IF ( trnp_count  == 0 )  trnp_count  = 1
2534          IF ( trnpt_count == 0 )  trnpt_count = 1
2535
2536          ALLOCATE( trsp(trsp_count), trnp(trnp_count) )
2537
2538          trsp = particle_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
2539                                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
2540                                0.0, 0, 0, 0, 0 )
2541          trnp = particle_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
2542                                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
2543                                0.0, 0, 0, 0, 0 )
2544
2545          IF ( use_particle_tails )  THEN
2546             ALLOCATE( trspt(maximum_number_of_tailpoints,5,trspt_count), &
2547                       trnpt(maximum_number_of_tailpoints,5,trnpt_count) )
2548             tlength = maximum_number_of_tailpoints * 5
2549          ENDIF
2550
2551          trsp_count  = 0
2552          trspt_count = 0
2553          trnp_count  = 0
2554          trnpt_count = 0
2555
2556       ENDIF
2557
2558!    WRITE ( 9, * ) '*** advec_particles: ##4'
2559!    CALL local_flush( 9 )
2560!    nd = 0
2561!    DO  n = 1, number_of_particles
2562!       IF ( .NOT. particle_mask(n) )  nd = nd + 1
2563!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
2564!       THEN
2565!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
2566!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
2567!          CALL local_flush( 9 )
2568!          CALL MPI_ABORT( comm2d, 9999, ierr )
2569!       ENDIF
2570!    ENDDO
2571!    IF ( nd /= deleted_particles ) THEN
2572!       WRITE (9,*) '*** nd=',nd,' deleted_particles=',deleted_particles
2573!       CALL local_flush( 9 )
2574!       CALL MPI_ABORT( comm2d, 9999, ierr )
2575!    ENDIF
2576
2577       DO  n = 1, number_of_particles
2578
2579          nn = particles(n)%tail_id
2580!
2581!--       Only those particles that have not been marked as 'deleted' may be
2582!--       moved.
2583          IF ( particle_mask(n) )  THEN
2584             j = ( particles(n)%y + 0.5 * dy ) * ddy
2585!
2586!--          Above calculation does not work for indices less than zero
2587             IF ( particles(n)%y < -0.5 * dy )  j = -1
2588
2589             IF ( j < nys )  THEN
2590                IF ( j < 0 )  THEN
2591!
2592!--                Apply boundary condition along y
2593                   IF ( ibc_par_ns == 0 )  THEN
2594!
2595!--                   Cyclic condition
2596                      IF ( pdims(2) == 1 )  THEN
2597                         particles(n)%y = ( ny + 1 ) * dy + particles(n)%y
2598                         particles(n)%origin_y = ( ny + 1 ) * dy + &
2599                                                 particles(n)%origin_y
2600                         IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2601                            i = particles(n)%tailpoints
2602                            particle_tail_coordinates(1:i,2,nn) = ( ny+1 ) * dy&
2603                                           + particle_tail_coordinates(1:i,2,nn)
2604                         ENDIF
2605                      ELSE
2606                         trsp_count = trsp_count + 1
2607                         trsp(trsp_count) = particles(n)
2608                         trsp(trsp_count)%y = ( ny + 1 ) * dy + &
2609                                              trsp(trsp_count)%y
2610                         trsp(trsp_count)%origin_y = trsp(trsp_count)%origin_y &
2611                                              + ( ny + 1 ) * dy
2612                         particle_mask(n) = .FALSE.
2613                         deleted_particles = deleted_particles + 1
2614
2615                         IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2616                            trspt_count = trspt_count + 1
2617                            trspt(:,:,trspt_count) = &
2618                                               particle_tail_coordinates(:,:,nn)
2619                            trspt(:,2,trspt_count) = ( ny + 1 ) * dy + &
2620                                                     trspt(:,2,trspt_count)
2621                            tail_mask(nn) = .FALSE.
2622                            deleted_tails = deleted_tails + 1
2623                         ENDIF
2624                      ENDIF
2625
2626                   ELSEIF ( ibc_par_ns == 1 )  THEN
2627!
2628!--                   Particle absorption
2629                      particle_mask(n) = .FALSE.
2630                      deleted_particles = deleted_particles + 1
2631                      IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2632                         tail_mask(nn) = .FALSE.
2633                         deleted_tails = deleted_tails + 1
2634                      ENDIF
2635
2636                   ELSEIF ( ibc_par_ns == 2 )  THEN
2637!
2638!--                   Particle reflection
2639                      particles(n)%y       = -particles(n)%y
2640                      particles(n)%speed_y = -particles(n)%speed_y
2641
2642                   ENDIF
2643                ELSE
2644!
2645!--                Store particle data in the transfer array, which will be send
2646!--                to the neighbouring PE
2647                   trsp_count = trsp_count + 1
2648                   trsp(trsp_count) = particles(n)
2649                   particle_mask(n) = .FALSE.
2650                   deleted_particles = deleted_particles + 1
2651
2652                   IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2653                      trspt_count = trspt_count + 1
2654                      trspt(:,:,trspt_count) = particle_tail_coordinates(:,:,nn)
2655                      tail_mask(nn) = .FALSE.
2656                      deleted_tails = deleted_tails + 1
2657                   ENDIF
2658                ENDIF
2659
2660             ELSEIF ( j > nyn )  THEN
2661                IF ( j > ny )  THEN
2662!
2663!--                Apply boundary condition along x
2664                   IF ( ibc_par_ns == 0 )  THEN
2665!
2666!--                   Cyclic condition
2667                      IF ( pdims(2) == 1 )  THEN
2668                         particles(n)%y = particles(n)%y - ( ny + 1 ) * dy
2669                         particles(n)%origin_y = particles(n)%origin_y - &
2670                                                 ( ny + 1 ) * dy
2671                         IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2672                            i = particles(n)%tailpoints
2673                            particle_tail_coordinates(1:i,2,nn) = - (ny+1) * dy&
2674                                           + particle_tail_coordinates(1:i,2,nn)
2675                         ENDIF
2676                      ELSE
2677                         trnp_count = trnp_count + 1
2678                         trnp(trnp_count) = particles(n)
2679                         trnp(trnp_count)%y = trnp(trnp_count)%y - &
2680                                              ( ny + 1 ) * dy
2681                         trnp(trnp_count)%origin_y = trnp(trnp_count)%origin_y &
2682                                                     - ( ny + 1 ) * dy
2683                         particle_mask(n) = .FALSE.
2684                         deleted_particles = deleted_particles + 1
2685
2686                         IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2687                            trnpt_count = trnpt_count + 1
2688                            trnpt(:,:,trnpt_count) = &
2689                                               particle_tail_coordinates(:,:,nn)
2690                            trnpt(:,2,trnpt_count) = trnpt(:,2,trnpt_count) - &
2691                                                     ( ny + 1 ) * dy
2692                            tail_mask(nn) = .FALSE.
2693                            deleted_tails = deleted_tails + 1
2694                         ENDIF
2695                      ENDIF
2696
2697                   ELSEIF ( ibc_par_ns == 1 )  THEN
2698!
2699!--                   Particle absorption
2700                      particle_mask(n) = .FALSE.
2701                      deleted_particles = deleted_particles + 1
2702                      IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2703                         tail_mask(nn) = .FALSE.
2704                         deleted_tails = deleted_tails + 1
2705                      ENDIF
2706
2707                   ELSEIF ( ibc_par_ns == 2 )  THEN
2708!
2709!--                   Particle reflection
2710                      particles(n)%y       = 2 * ( ny * dy ) - particles(n)%y
2711                      particles(n)%speed_y = -particles(n)%speed_y
2712
2713                   ENDIF
2714                ELSE
2715!
2716!--                Store particle data in the transfer array, which will be send
2717!--                to the neighbouring PE
2718                   trnp_count = trnp_count + 1
2719                   trnp(trnp_count) = particles(n)
2720                   particle_mask(n) = .FALSE.
2721                   deleted_particles = deleted_particles + 1
2722
2723                   IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2724                      trnpt_count = trnpt_count + 1
2725                      trnpt(:,:,trnpt_count) = particle_tail_coordinates(:,:,nn)
2726                      tail_mask(nn) = .FALSE.
2727                      deleted_tails = deleted_tails + 1
2728                   ENDIF
2729                ENDIF
2730
2731             ENDIF
2732          ENDIF
2733       ENDDO
2734
2735!    WRITE ( 9, * ) '*** advec_particles: ##5'
2736!    CALL local_flush( 9 )
2737!    nd = 0
2738!    DO  n = 1, number_of_particles
2739!       IF ( .NOT. particle_mask(n) )  nd = nd + 1
2740!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
2741!       THEN
2742!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
2743!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
2744!          CALL local_flush( 9 )
2745!          CALL MPI_ABORT( comm2d, 9999, ierr )
2746!       ENDIF
2747!    ENDDO
2748!    IF ( nd /= deleted_particles ) THEN
2749!       WRITE (9,*) '*** nd=',nd,' deleted_particles=',deleted_particles
2750!       CALL local_flush( 9 )
2751!       CALL MPI_ABORT( comm2d, 9999, ierr )
2752!    ENDIF
2753
2754!
2755!--    Send front boundary, receive back boundary (but first exchange how many
2756!--    and check, if particle storage must be extended)
2757       IF ( pdims(2) /= 1 )  THEN
2758
2759          CALL cpu_log( log_point_s(23), 'sendrcv_particles', 'continue' )
2760          CALL MPI_SENDRECV( trsp_count,      1, MPI_INTEGER, psouth, 0, &
2761                             trnp_count_recv, 1, MPI_INTEGER, pnorth, 0, &
2762                             comm2d, status, ierr )
2763
2764          IF ( number_of_particles + trnp_count_recv > &
2765               maximum_number_of_particles )           &
2766          THEN
2767             IF ( netcdf_output )  THEN
2768                message_string = 'maximum_number_of_particles ' // &
2769                                 'needs to be increased ' // &
2770                                 '&but this is not allowed with '// &
2771                                 'NetCDF output switched on'
2772                CALL message( 'advec_particles', 'PA0146', 2, 2, 0, 6, 0 ) 
2773             ELSE
2774!    WRITE ( 9, * ) '*** advec_particles: before allocate_prt_memory trnp'
2775!    CALL local_flush( 9 )
2776                CALL allocate_prt_memory( trnp_count_recv )
2777!    WRITE ( 9, * ) '*** advec_particles: after allocate_prt_memory trnp'
2778!    CALL local_flush( 9 )
2779             ENDIF
2780          ENDIF
2781
2782          CALL MPI_SENDRECV( trsp(1)%age, trsp_count, mpi_particle_type,      &
2783                             psouth, 1, particles(number_of_particles+1)%age, &
2784                             trnp_count_recv, mpi_particle_type, pnorth, 1,   &
2785                             comm2d, status, ierr )
2786
2787          IF ( use_particle_tails )  THEN
2788
2789             CALL MPI_SENDRECV( trspt_count,      1, MPI_INTEGER, psouth, 0, &
2790                                trnpt_count_recv, 1, MPI_INTEGER, pnorth, 0, &
2791                                comm2d, status, ierr )
2792
2793             IF ( number_of_tails+trnpt_count_recv > maximum_number_of_tails ) &
2794             THEN
2795                IF ( netcdf_output )  THEN
2796                   message_string = 'maximum_number_of_tails ' // &
2797                                    'needs to be increased ' // &
2798                                    '&but this is not allowed wi' // &
2799                                    'th NetCDF output switched on'
2800                   CALL message( 'advec_particles', 'PA0147', 2, 2, 0, 6, 0 ) 
2801                ELSE
2802!    WRITE ( 9, * ) '*** advec_particles: before allocate_tail_memory trnpt'
2803!    CALL local_flush( 9 )
2804                   CALL allocate_tail_memory( trnpt_count_recv )
2805!    WRITE ( 9, * ) '*** advec_particles: after allocate_tail_memory trnpt'
2806!    CALL local_flush( 9 )
2807                ENDIF
2808             ENDIF
2809
2810             CALL MPI_SENDRECV( trspt(1,1,1), trspt_count*tlength, MPI_REAL,   &
2811                                psouth, 1,                                     &
2812                             particle_tail_coordinates(1,1,number_of_tails+1), &
2813                                trnpt_count_recv*tlength, MPI_REAL, pnorth, 1, &
2814                                comm2d, status, ierr )
2815!
2816!--          Update the tail ids for the transferred particles
2817             nn = number_of_tails
2818             DO  n = number_of_particles+1, number_of_particles+trnp_count_recv
2819                IF ( particles(n)%tail_id /= 0 )  THEN
2820                   nn = nn + 1
2821                   particles(n)%tail_id = nn
2822                ENDIF
2823             ENDDO
2824
2825          ENDIF
2826
2827          number_of_particles = number_of_particles + trnp_count_recv
2828          number_of_tails     = number_of_tails     + trnpt_count_recv
2829!       IF ( number_of_particles /= number_of_tails )  THEN
2830!          WRITE (9,*) '--- advec_particles: #5'
2831!          WRITE (9,*) '    #of p=',number_of_particles,' #of t=',number_of_tails
2832!          CALL local_flush( 9 )
2833!       ENDIF
2834
2835!
2836!--       Send back boundary, receive front boundary
2837          CALL MPI_SENDRECV( trnp_count,      1, MPI_INTEGER, pnorth, 0, &
2838                             trsp_count_recv, 1, MPI_INTEGER, psouth, 0, &
2839                             comm2d, status, ierr )
2840
2841          IF ( number_of_particles + trsp_count_recv > &
2842               maximum_number_of_particles )           &
2843          THEN
2844             IF ( netcdf_output )  THEN
2845                message_string = 'maximum_number_of_particles ' // &
2846                                 'needs to be increased ' // &
2847                                 '&but this is not allowed with ' // &
2848                                 'NetCDF output switched on'
2849               CALL message( 'advec_particles', 'PA0146', 2, 2, 0, 6, 0 ) 
2850             ELSE
2851!    WRITE ( 9, * ) '*** advec_particles: before allocate_prt_memory trsp'
2852!    CALL local_flush( 9 )
2853                CALL allocate_prt_memory( trsp_count_recv )
2854!    WRITE ( 9, * ) '*** advec_particles: after allocate_prt_memory trsp'
2855!    CALL local_flush( 9 )
2856             ENDIF
2857          ENDIF
2858
2859          CALL MPI_SENDRECV( trnp(1)%age, trnp_count, mpi_particle_type,      &
2860                             pnorth, 1, particles(number_of_particles+1)%age, &
2861                             trsp_count_recv, mpi_particle_type, psouth, 1,   &
2862                             comm2d, status, ierr )
2863
2864          IF ( use_particle_tails )  THEN
2865
2866             CALL MPI_SENDRECV( trnpt_count,      1, MPI_INTEGER, pnorth, 0, &
2867                                trspt_count_recv, 1, MPI_INTEGER, psouth, 0, &
2868                                comm2d, status, ierr )
2869
2870             IF ( number_of_tails+trspt_count_recv > maximum_number_of_tails ) &
2871             THEN
2872                IF ( netcdf_output )  THEN
2873                   message_string = 'maximum_number_of_tails ' // &
2874                                    'needs to be increased ' // &
2875                                    '&but this is not allowed wi'// &
2876                                    'th NetCDF output switched on'
2877                   CALL message( 'advec_particles', 'PA0147', 2, 2, 0, 6, 0 )
2878                ELSE
2879!    WRITE ( 9, * ) '*** advec_particles: before allocate_tail_memory trspt'
2880!    CALL local_flush( 9 )
2881                   CALL allocate_tail_memory( trspt_count_recv )
2882!    WRITE ( 9, * ) '*** advec_particles: after allocate_tail_memory trspt'
2883!    CALL local_flush( 9 )
2884                ENDIF
2885             ENDIF
2886
2887             CALL MPI_SENDRECV( trnpt(1,1,1), trnpt_count*tlength, MPI_REAL,   &
2888                                pnorth, 1,                                     &
2889                             particle_tail_coordinates(1,1,number_of_tails+1), &
2890                                trspt_count_recv*tlength, MPI_REAL, psouth, 1, &
2891                                comm2d, status, ierr )
2892!
2893!--          Update the tail ids for the transferred particles
2894             nn = number_of_tails
2895             DO  n = number_of_particles+1, number_of_particles+trsp_count_recv
2896                IF ( particles(n)%tail_id /= 0 )  THEN
2897                   nn = nn + 1
2898                   particles(n)%tail_id = nn
2899                ENDIF
2900             ENDDO
2901
2902          ENDIF
2903
2904          number_of_particles = number_of_particles + trsp_count_recv
2905          number_of_tails     = number_of_tails     + trspt_count_recv
2906!       IF ( number_of_particles /= number_of_tails )  THEN
2907!          WRITE (9,*) '--- advec_particles: #6'
2908!          WRITE (9,*) '    #of p=',number_of_particles,' #of t=',number_of_tails
2909!          CALL local_flush( 9 )
2910!       ENDIF
2911
2912          IF ( use_particle_tails )  THEN
2913             DEALLOCATE( trspt, trnpt )
2914          ENDIF
2915          DEALLOCATE( trsp, trnp )
2916
2917          CALL cpu_log( log_point_s(23), 'sendrcv_particles', 'stop' )
2918
2919       ENDIF
2920
2921!    WRITE ( 9, * ) '*** advec_particles: ##6'
2922!    CALL local_flush( 9 )
2923!    nd = 0
2924!    DO  n = 1, number_of_particles
2925!       IF ( .NOT. particle_mask(n) )  nd = nd + 1
2926!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
2927!       THEN
2928!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
2929!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
2930!          CALL local_flush( 9 )
2931!          CALL MPI_ABORT( comm2d, 9999, ierr )
2932!       ENDIF
2933!    ENDDO
2934!    IF ( nd /= deleted_particles ) THEN
2935!       WRITE (9,*) '*** nd=',nd,' deleted_particles=',deleted_particles
2936!       CALL local_flush( 9 )
2937!       CALL MPI_ABORT( comm2d, 9999, ierr )
2938!    ENDIF
2939
2940#else
2941
2942!
2943!--    Apply boundary conditions
2944       DO  n = 1, number_of_particles
2945
2946          nn = particles(n)%tail_id
2947
2948          IF ( particles(n)%x < -0.5 * dx )  THEN
2949
2950             IF ( ibc_par_lr == 0 )  THEN
2951!
2952!--             Cyclic boundary. Relevant coordinate has to be changed.
2953                particles(n)%x = ( nx + 1 ) * dx + particles(n)%x
2954                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2955                   i = particles(n)%tailpoints
2956                   particle_tail_coordinates(1:i,1,nn) = ( nx + 1 ) * dx + &
2957                                             particle_tail_coordinates(1:i,1,nn)
2958                ENDIF
2959             ELSEIF ( ibc_par_lr == 1 )  THEN
2960!
2961!--             Particle absorption
2962                particle_mask(n) = .FALSE.
2963                deleted_particles = deleted_particles + 1
2964                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2965                   tail_mask(nn) = .FALSE.
2966                   deleted_tails = deleted_tails + 1
2967                ENDIF
2968             ELSEIF ( ibc_par_lr == 2 )  THEN
2969!
2970!--             Particle reflection
2971                particles(n)%x       = -dx - particles(n)%x
2972                particles(n)%speed_x = -particles(n)%speed_x
2973             ENDIF
2974
2975          ELSEIF ( particles(n)%x >= ( nx + 0.5 ) * dx )  THEN
2976
2977             IF ( ibc_par_lr == 0 )  THEN
2978!
2979!--             Cyclic boundary. Relevant coordinate has to be changed.
2980                particles(n)%x = particles(n)%x - ( nx + 1 ) * dx
2981                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2982                   i = particles(n)%tailpoints
2983                   particle_tail_coordinates(1:i,1,nn) = - ( nx + 1 ) * dx + &
2984                                             particle_tail_coordinates(1:i,1,nn)
2985                ENDIF
2986             ELSEIF ( ibc_par_lr == 1 )  THEN
2987!
2988!--             Particle absorption
2989                particle_mask(n) = .FALSE.
2990                deleted_particles = deleted_particles + 1
2991                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
2992                   tail_mask(nn) = .FALSE.
2993                   deleted_tails = deleted_tails + 1
2994                ENDIF
2995             ELSEIF ( ibc_par_lr == 2 )  THEN
2996!
2997!--             Particle reflection
2998                particles(n)%x       = ( nx + 1 ) * dx - particles(n)%x
2999                particles(n)%speed_x = -particles(n)%speed_x
3000             ENDIF
3001
3002          ENDIF
3003
3004          IF ( particles(n)%y < -0.5 * dy )  THEN
3005
3006             IF ( ibc_par_ns == 0 )  THEN
3007!
3008!--             Cyclic boundary. Relevant coordinate has to be changed.
3009                particles(n)%y = ( ny + 1 ) * dy + particles(n)%y
3010                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
3011                   i = particles(n)%tailpoints
3012                   particle_tail_coordinates(1:i,2,nn) = ( ny + 1 ) * dy + &
3013                                             particle_tail_coordinates(1:i,2,nn)
3014                ENDIF
3015             ELSEIF ( ibc_par_ns == 1 )  THEN
3016!
3017!--             Particle absorption
3018                particle_mask(n) = .FALSE.
3019                deleted_particles = deleted_particles + 1
3020                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
3021                   tail_mask(nn) = .FALSE.
3022                   deleted_tails = deleted_tails + 1
3023                ENDIF
3024             ELSEIF ( ibc_par_ns == 2 )  THEN
3025!
3026!--             Particle reflection
3027                particles(n)%y       = -dy - particles(n)%y
3028                particles(n)%speed_y = -particles(n)%speed_y
3029             ENDIF
3030
3031          ELSEIF ( particles(n)%y >= ( ny + 0.5 ) * dy )  THEN
3032
3033             IF ( ibc_par_ns == 0 )  THEN
3034!
3035!--             Cyclic boundary. Relevant coordinate has to be changed.
3036                particles(n)%y = particles(n)%y - ( ny + 1 ) * dy
3037                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
3038                   i = particles(n)%tailpoints
3039                   particle_tail_coordinates(1:i,2,nn) = - ( ny + 1 ) * dy + &
3040                                             particle_tail_coordinates(1:i,2,nn)
3041                ENDIF
3042             ELSEIF ( ibc_par_ns == 1 )  THEN
3043!
3044!--             Particle absorption
3045                particle_mask(n) = .FALSE.
3046                deleted_particles = deleted_particles + 1
3047                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
3048                   tail_mask(nn) = .FALSE.
3049                   deleted_tails = deleted_tails + 1
3050                ENDIF
3051             ELSEIF ( ibc_par_ns == 2 )  THEN
3052!
3053!--             Particle reflection
3054                particles(n)%y       = ( ny + 1 ) * dy - particles(n)%y
3055                particles(n)%speed_y = -particles(n)%speed_y
3056             ENDIF
3057
3058          ENDIF
3059       ENDDO
3060
3061#endif
3062
3063!
3064!--    Apply boundary conditions to those particles that have crossed the top or
3065!--    bottom boundary and delete those particles, which are older than allowed
3066       DO  n = 1, number_of_particles
3067
3068          nn = particles(n)%tail_id
3069
3070!
3071!--       Stop if particles have moved further than the length of one
3072!--       PE subdomain (newly released particles have age = age_m!)
3073          IF ( particles(n)%age /= particles(n)%age_m )  THEN
3074             IF ( ABS(particles(n)%speed_x) >                                  &
3075                  ((nxr-nxl+2)*dx)/(particles(n)%age-particles(n)%age_m)  .OR. &
3076                  ABS(particles(n)%speed_y) >                                  &
3077                  ((nyn-nys+2)*dy)/(particles(n)%age-particles(n)%age_m) )  THEN
3078
3079                  WRITE( message_string, * )  'particle too fast.  n = ',  n 
3080                  CALL message( 'advec_particles', 'PA0148', 2, 2, 0, 6, 0 )
3081             ENDIF
3082          ENDIF
3083
3084          IF ( particles(n)%age > particle_maximum_age  .AND.  &
3085               particle_mask(n) )                              &
3086          THEN
3087             particle_mask(n)  = .FALSE.
3088             deleted_particles = deleted_particles + 1
3089             IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
3090                tail_mask(nn) = .FALSE.
3091                deleted_tails = deleted_tails + 1
3092             ENDIF
3093          ENDIF
3094
3095          IF ( particles(n)%z >= zu(nz)  .AND.  particle_mask(n) )  THEN
3096             IF ( ibc_par_t == 1 )  THEN
3097!
3098!--             Particle absorption
3099                particle_mask(n)  = .FALSE.
3100                deleted_particles = deleted_particles + 1
3101                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
3102                   tail_mask(nn) = .FALSE.
3103                   deleted_tails = deleted_tails + 1
3104                ENDIF
3105             ELSEIF ( ibc_par_t == 2 )  THEN
3106!
3107!--             Particle reflection
3108                particles(n)%z       = 2.0 * zu(nz) - particles(n)%z
3109                particles(n)%speed_z = -particles(n)%speed_z
3110                IF ( use_sgs_for_particles  .AND. &
3111                     particles(n)%speed_z_sgs > 0.0 )  THEN
3112                   particles(n)%speed_z_sgs = -particles(n)%speed_z_sgs
3113                ENDIF
3114                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
3115                   particle_tail_coordinates(1,3,nn) = 2.0 * zu(nz) - &
3116                                               particle_tail_coordinates(1,3,nn)
3117                ENDIF
3118             ENDIF
3119          ENDIF
3120          IF ( particles(n)%z < zw(0)  .AND.  particle_mask(n) )  THEN
3121             IF ( ibc_par_b == 1 )  THEN
3122!
3123!--             Particle absorption
3124                particle_mask(n)  = .FALSE.
3125                deleted_particles = deleted_particles + 1
3126                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
3127                   tail_mask(nn) = .FALSE.
3128                   deleted_tails = deleted_tails + 1
3129                ENDIF
3130             ELSEIF ( ibc_par_b == 2 )  THEN
3131!
3132!--             Particle reflection
3133                particles(n)%z       = 2.0 * zw(0) - particles(n)%z
3134                particles(n)%speed_z = -particles(n)%speed_z
3135                IF ( use_sgs_for_particles  .AND. &
3136                     particles(n)%speed_z_sgs < 0.0 )  THEN
3137                   particles(n)%speed_z_sgs = -particles(n)%speed_z_sgs
3138                ENDIF
3139                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
3140                   particle_tail_coordinates(1,3,nn) = 2.0 * zu(nz) - &
3141                                               particle_tail_coordinates(1,3,nn)
3142                ENDIF
3143                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
3144                   particle_tail_coordinates(1,3,nn) = 2.0 * zw(0) - &
3145                                               particle_tail_coordinates(1,3,nn)
3146                ENDIF
3147             ENDIF
3148          ENDIF
3149       ENDDO
3150
3151!    WRITE ( 9, * ) '*** advec_particles: ##7'
3152!    CALL local_flush( 9 )
3153!    nd = 0
3154!    DO  n = 1, number_of_particles
3155!       IF ( .NOT. particle_mask(n) )  nd = nd + 1
3156!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
3157!       THEN
3158!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
3159!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
3160!          CALL local_flush( 9 )
3161!          CALL MPI_ABORT( comm2d, 9999, ierr )
3162!       ENDIF
3163!    ENDDO
3164!    IF ( nd /= deleted_particles ) THEN
3165!       WRITE (9,*) '*** nd=',nd,' deleted_particles=',deleted_particles
3166!       CALL local_flush( 9 )
3167!       CALL MPI_ABORT( comm2d, 9999, ierr )
3168!    ENDIF
3169
3170!
3171!--    Pack particles (eliminate those marked for deletion),
3172!--    determine new number of particles
3173       IF ( number_of_particles > 0  .AND.  deleted_particles > 0 )  THEN
3174          nn = 0
3175          nd = 0
3176          DO  n = 1, number_of_particles
3177             IF ( particle_mask(n) )  THEN
3178                nn = nn + 1
3179                particles(nn) = particles(n)
3180             ELSE
3181                nd = nd + 1
3182             ENDIF
3183          ENDDO
3184!       IF ( nd /= deleted_particles ) THEN
3185!          WRITE (9,*) '*** advec_part nd=',nd,' deleted_particles=',deleted_particles
3186!          CALL local_flush( 9 )
3187!          CALL MPI_ABORT( comm2d, 9999, ierr )
3188!       ENDIF
3189
3190          number_of_particles = number_of_particles - deleted_particles
3191!
3192!--       Pack the tails, store the new tail ids and re-assign it to the
3193!--       respective
3194!--       particles
3195          IF ( use_particle_tails )  THEN
3196             nn = 0
3197             nd = 0
3198             DO  n = 1, number_of_tails
3199                IF ( tail_mask(n) )  THEN
3200                   nn = nn + 1
3201                   particle_tail_coordinates(:,:,nn) = &
3202                                                particle_tail_coordinates(:,:,n)
3203                   new_tail_id(n) = nn
3204                ELSE
3205                   nd = nd + 1
3206!                WRITE (9,*) '+++ n=',n,' (of ',number_of_tails,' #oftails)'
3207!                WRITE (9,*) '    id=',new_tail_id(n)
3208!                CALL local_flush( 9 )
3209                ENDIF
3210             ENDDO
3211          ENDIF
3212
3213!       IF ( nd /= deleted_tails  .AND.  use_particle_tails ) THEN
3214!          WRITE (9,*) '*** advec_part nd=',nd,' deleted_tails=',deleted_tails
3215!          CALL local_flush( 9 )
3216!          CALL MPI_ABORT( comm2d, 9999, ierr )
3217!       ENDIF
3218
3219          number_of_tails = number_of_tails - deleted_tails
3220
3221!     nn = 0
3222          DO  n = 1, number_of_particles
3223             IF ( particles(n)%tail_id /= 0 )  THEN
3224!     nn = nn + 1
3225!     IF (  particles(n)%tail_id<0 .OR. particles(n)%tail_id > number_of_tails )  THEN
3226!        WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
3227!        WRITE (9,*) '    tail_id=',particles(n)%tail_id
3228!        WRITE (9,*) '    new_tail_id=', new_tail_id(particles(n)%tail_id), &
3229!                         ' of (',number_of_tails,')'
3230!        CALL local_flush( 9 )
3231!     ENDIF
3232                particles(n)%tail_id = new_tail_id(particles(n)%tail_id)
3233             ENDIF
3234          ENDDO
3235
3236!     IF ( nn /= number_of_tails  .AND.  use_particle_tails ) THEN
3237!        WRITE (9,*) '*** advec_part #of_tails=',number_of_tails,' nn=',nn
3238!        CALL local_flush( 9 )
3239!        DO  n = 1, number_of_particles
3240!           WRITE (9,*) 'prt# ',n,' tail_id=',particles(n)%tail_id, &
3241!                       ' x=',particles(n)%x, ' y=',particles(n)%y, &
3242!                       ' z=',particles(n)%z
3243!        ENDDO
3244!        CALL MPI_ABORT( comm2d, 9999, ierr )
3245!     ENDIF
3246
3247       ENDIF
3248
3249!    IF ( number_of_particles /= number_of_tails )  THEN
3250!       WRITE (9,*) '--- advec_particles: #7'
3251!       WRITE (9,*) '    #of p=',number_of_particles,' #of t=',number_of_tails
3252!       CALL local_flush( 9 )
3253!    ENDIF
3254!    WRITE ( 9, * ) '*** advec_particles: ##8'
3255!    CALL local_flush( 9 )
3256!    DO  n = 1, number_of_particles
3257!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
3258!       THEN
3259!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
3260!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
3261!          CALL local_flush( 9 )
3262!          CALL MPI_ABORT( comm2d, 9999, ierr )
3263!       ENDIF
3264!    ENDDO
3265
3266!    WRITE ( 9, * ) '*** advec_particles: ##9'
3267!    CALL local_flush( 9 )
3268!    DO  n = 1, number_of_particles
3269!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
3270!       THEN
3271!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
3272!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
3273!          CALL local_flush( 9 )
3274!          CALL MPI_ABORT( comm2d, 9999, ierr )
3275!       ENDIF
3276!    ENDDO
3277
3278!
3279!--    Accumulate the number of particles transferred between the subdomains
3280#if defined( __parallel )
3281       trlp_count_sum      = trlp_count_sum      + trlp_count
3282       trlp_count_recv_sum = trlp_count_recv_sum + trlp_count_recv
3283       trrp_count_sum      = trrp_count_sum      + trrp_count
3284       trrp_count_recv_sum = trrp_count_recv_sum + trrp_count_recv
3285       trsp_count_sum      = trsp_count_sum      + trsp_count
3286       trsp_count_recv_sum = trsp_count_recv_sum + trsp_count_recv
3287       trnp_count_sum      = trnp_count_sum      + trnp_count
3288       trnp_count_recv_sum = trnp_count_recv_sum + trnp_count_recv
3289#endif
3290
3291       IF ( dt_3d_reached )  EXIT
3292
3293    ENDDO   ! timestep loop
3294
3295
3296!
3297!-- Sort particles in the sequence the gridboxes are stored in the memory
3298    time_sort_particles = time_sort_particles + dt_3d
3299    IF ( time_sort_particles >= dt_sort_particles )  THEN
3300       CALL sort_particles
3301       time_sort_particles = MOD( time_sort_particles, &
3302                                  MAX( dt_sort_particles, dt_3d ) )
3303    ENDIF
3304
3305
3306!
3307!-- Re-evaluate the weighting factors. After advection, particles within a
3308!-- grid box may have different weighting factors if some have been advected
3309!-- from a neighbouring box. The factors are re-evaluated so that they are
3310!-- the same for all particles of one box. This procedure must conserve the
3311!-- liquid water content within one box.
3312    IF ( cloud_droplets )  THEN
3313
3314       CALL cpu_log( log_point_s(45), 'advec_part_reeval_we', 'start' )
3315
3316       ql = 0.0;  ql_v = 0.0;  ql_vp = 0.0
3317
3318!
3319!--    Re-calculate the weighting factors and calculate the liquid water content
3320       DO  i = nxl, nxr
3321          DO  j = nys, nyn
3322             DO  k = nzb, nzt+1
3323
3324!
3325!--             Calculate the total volume of particles in the boxes (ql_vp) as
3326!--             well as the real volume (ql_v, weighting factor has to be
3327!--             included)
3328                psi = prt_start_index(k,j,i)
3329                DO  n = psi, psi+prt_count(k,j,i)-1
3330                   ql_vp(k,j,i) = ql_vp(k,j,i) + particles(n)%radius**3
3331
3332                   ql_v(k,j,i)  = ql_v(k,j,i)  + particles(n)%weight_factor * &
3333                                                 particles(n)%radius**3
3334                ENDDO
3335
3336!
3337!--             Re-calculate the weighting factors and calculate the liquid
3338!--             water content
3339                IF ( ql_vp(k,j,i) /= 0.0 )  THEN
3340                   ql_vp(k,j,i) = ql_v(k,j,i) / ql_vp(k,j,i)
3341                   ql(k,j,i) = ql(k,j,i) + rho_l * 1.33333333 * pi * &
3342                                           ql_v(k,j,i) /             &
3343                                           ( rho_surface * dx * dy * dz )
3344                ELSE
3345                   ql(k,j,i) = 0.0
3346                ENDIF
3347
3348!
3349!--             Re-assign the weighting factor to the particles
3350                DO  n = psi, psi+prt_count(k,j,i)-1
3351                   particles(n)%weight_factor = ql_vp(k,j,i)
3352                ENDDO
3353
3354             ENDDO
3355          ENDDO
3356       ENDDO
3357
3358       CALL cpu_log( log_point_s(45), 'advec_part_reeval_we', 'stop' )
3359
3360    ENDIF
3361
3362!
3363!-- Set particle attributes
3364    CALL set_particle_attributes
3365
3366!
3367!-- Set particle attributes defined by the user
3368    CALL user_particle_attributes
3369!    WRITE ( 9, * ) '*** advec_particles: ##10'
3370!    CALL local_flush( 9 )
3371!    DO  n = 1, number_of_particles
3372!       IF ( particles(n)%tail_id<0 .OR. particles(n)%tail_id>number_of_tails ) &
3373!       THEN
3374!          WRITE (9,*) '+++ n=',n,' (of ',number_of_particles,')'
3375!          WRITE (9,*) '    id=',particles(n)%tail_id,' of (',number_of_tails,')'
3376!          CALL local_flush( 9 )
3377!          CALL MPI_ABORT( comm2d, 9999, ierr )
3378!       ENDIF
3379!    ENDDO
3380
3381!
3382!-- If necessary, add the actual particle positions to the particle tails
3383    IF ( use_particle_tails )  THEN
3384
3385       distance = 0.0
3386       DO  n = 1, number_of_particles
3387
3388          nn = particles(n)%tail_id
3389
3390          IF ( nn /= 0 )  THEN
3391!
3392!--          Calculate the distance between the actual particle position and the
3393!--          next tailpoint
3394!             WRITE ( 9, * ) '*** advec_particles: ##10.1  nn=',nn
3395!             CALL local_flush( 9 )
3396             IF ( minimum_tailpoint_distance /= 0.0 )  THEN
3397                distance = ( particle_tail_coordinates(1,1,nn) -      &
3398                             particle_tail_coordinates(2,1,nn) )**2 + &
3399                           ( particle_tail_coordinates(1,2,nn) -      &
3400                             particle_tail_coordinates(2,2,nn) )**2 + &
3401                           ( particle_tail_coordinates(1,3,nn) -      &
3402                             particle_tail_coordinates(2,3,nn) )**2
3403             ENDIF
3404!             WRITE ( 9, * ) '*** advec_particles: ##10.2'
3405!             CALL local_flush( 9 )
3406!
3407!--          First, increase the index of all existings tailpoints by one
3408             IF ( distance >= minimum_tailpoint_distance )  THEN
3409                DO i = particles(n)%tailpoints, 1, -1
3410                   particle_tail_coordinates(i+1,:,nn) = &
3411                                               particle_tail_coordinates(i,:,nn)
3412                ENDDO
3413!
3414!--             Increase the counter which contains the number of tailpoints.
3415!--             This must always be smaller than the given maximum number of
3416!--             tailpoints because otherwise the index bounds of
3417!--             particle_tail_coordinates would be exceeded
3418                IF ( particles(n)%tailpoints < maximum_number_of_tailpoints-1 )&
3419                THEN
3420                   particles(n)%tailpoints = particles(n)%tailpoints + 1
3421                ENDIF
3422             ENDIF
3423!             WRITE ( 9, * ) '*** advec_particles: ##10.3'
3424!             CALL local_flush( 9 )
3425!
3426!--          In any case, store the new point at the beginning of the tail
3427             particle_tail_coordinates(1,1,nn) = particles(n)%x
3428             particle_tail_coordinates(1,2,nn) = particles(n)%y
3429             particle_tail_coordinates(1,3,nn) = particles(n)%z
3430             particle_tail_coordinates(1,4,nn) = particles(n)%color
3431!             WRITE ( 9, * ) '*** advec_particles: ##10.4'
3432!             CALL local_flush( 9 )
3433!
3434!--          Increase the age of the tailpoints
3435             IF ( minimum_tailpoint_distance /= 0.0 )  THEN
3436                particle_tail_coordinates(2:particles(n)%tailpoints,5,nn) =    &
3437                   particle_tail_coordinates(2:particles(n)%tailpoints,5,nn) + &
3438                   dt_3d
3439!
3440!--             Delete the last tailpoint, if it has exceeded its maximum age
3441                IF ( particle_tail_coordinates(particles(n)%tailpoints,5,nn) > &
3442                     maximum_tailpoint_age )  THEN
3443                   particles(n)%tailpoints = particles(n)%tailpoints - 1
3444                ENDIF
3445             ENDIF
3446!             WRITE ( 9, * ) '*** advec_particles: ##10.5'
3447!             CALL local_flush( 9 )
3448
3449          ENDIF
3450
3451       ENDDO
3452
3453    ENDIF
3454!    WRITE ( 9, * ) '*** advec_particles: ##11'
3455!    CALL local_flush( 9 )
3456
3457!
3458!-- Write particle statistics on file
3459    IF ( write_particle_statistics )  THEN
3460       CALL check_open( 80 )
3461#if defined( __parallel )
3462       WRITE ( 80, 8000 )  current_timestep_number+1, simulated_time+dt_3d, &
3463                           number_of_particles, pleft, trlp_count_sum,      &
3464                           trlp_count_recv_sum, pright, trrp_count_sum,     &
3465                           trrp_count_recv_sum, psouth, trsp_count_sum,     &
3466                           trsp_count_recv_sum, pnorth, trnp_count_sum,     &
3467                           trnp_count_recv_sum, maximum_number_of_particles
3468       CALL close_file( 80 )
3469#else
3470       WRITE ( 80, 8000 )  current_timestep_number+1, simulated_time+dt_3d, &
3471                           number_of_particles, maximum_number_of_particles
3472#endif
3473    ENDIF
3474
3475    CALL cpu_log( log_point(25), 'advec_particles', 'stop' )
3476
3477!
3478!-- Formats
34798000 FORMAT (I6,1X,F7.2,4X,I6,5X,4(I3,1X,I4,'/',I4,2X),6X,I6)
3480
3481 END SUBROUTINE advec_particles
3482
3483
3484 SUBROUTINE allocate_prt_memory( number_of_new_particles )
3485
3486!------------------------------------------------------------------------------!
3487! Description:
3488! ------------
3489! Extend particle memory
3490!------------------------------------------------------------------------------!
3491
3492    USE particle_attributes
3493
3494    IMPLICIT NONE
3495
3496    INTEGER ::  new_maximum_number, number_of_new_particles
3497
3498    LOGICAL, DIMENSION(:), ALLOCATABLE ::  tmp_particle_mask
3499
3500    TYPE(particle_type), DIMENSION(:), ALLOCATABLE ::  tmp_particles
3501
3502
3503    new_maximum_number = maximum_number_of_particles + &
3504                   MAX( 5*number_of_new_particles, number_of_initial_particles )
3505
3506    IF ( write_particle_statistics )  THEN
3507       CALL check_open( 80 )
3508       WRITE ( 80, '(''*** Request: '', I7, '' new_maximum_number(prt)'')' ) &
3509                            new_maximum_number
3510       CALL close_file( 80 )
3511    ENDIF
3512
3513    ALLOCATE( tmp_particles(maximum_number_of_particles), &
3514              tmp_particle_mask(maximum_number_of_particles) )
3515    tmp_particles     = particles
3516    tmp_particle_mask = particle_mask
3517
3518    DEALLOCATE( particles, particle_mask )
3519    ALLOCATE( particles(new_maximum_number), &
3520              particle_mask(new_maximum_number) )
3521    maximum_number_of_particles = new_maximum_number
3522
3523    particles(1:number_of_particles) = tmp_particles(1:number_of_particles)
3524    particle_mask(1:number_of_particles) = &
3525                                  tmp_particle_mask(1:number_of_particles)
3526    particle_mask(number_of_particles+1:maximum_number_of_particles) = .TRUE.
3527    DEALLOCATE( tmp_particles, tmp_particle_mask )
3528
3529 END SUBROUTINE allocate_prt_memory
3530
3531
3532 SUBROUTINE allocate_tail_memory( number_of_new_tails )
3533
3534!------------------------------------------------------------------------------!
3535! Description:
3536! ------------
3537! Extend tail memory
3538!------------------------------------------------------------------------------!
3539
3540    USE particle_attributes
3541
3542    IMPLICIT NONE
3543
3544    INTEGER ::  new_maximum_number, number_of_new_tails
3545
3546    LOGICAL, DIMENSION(maximum_number_of_tails) ::  tmp_tail_mask
3547
3548    REAL, DIMENSION(maximum_number_of_tailpoints,5,maximum_number_of_tails) :: &
3549                                                    tmp_tail
3550
3551
3552    new_maximum_number = maximum_number_of_tails + &
3553                         MAX( 5*number_of_new_tails, number_of_initial_tails )
3554
3555    IF ( write_particle_statistics )  THEN
3556       CALL check_open( 80 )
3557       WRITE ( 80, '(''*** Request: '', I5, '' new_maximum_number(tails)'')' ) &
3558                            new_maximum_number
3559       CALL close_file( 80 )
3560    ENDIF
3561    WRITE (9,*) '*** Request: ',new_maximum_number,' new_maximum_number(tails)'
3562!    CALL local_flush( 9 )
3563
3564    tmp_tail(:,:,1:number_of_tails)  = &
3565                                particle_tail_coordinates(:,:,1:number_of_tails)
3566    tmp_tail_mask(1:number_of_tails) = tail_mask(1:number_of_tails)
3567
3568    DEALLOCATE( new_tail_id, particle_tail_coordinates, tail_mask )
3569    ALLOCATE( new_tail_id(new_maximum_number),                          &
3570              particle_tail_coordinates(maximum_number_of_tailpoints,5, &
3571              new_maximum_number),                                      &
3572              tail_mask(new_maximum_number) )
3573    maximum_number_of_tails = new_maximum_number
3574
3575    particle_tail_coordinates = 0.0
3576    particle_tail_coordinates(:,:,1:number_of_tails) = &
3577                                                 tmp_tail(:,:,1:number_of_tails)
3578    tail_mask(1:number_of_tails) = tmp_tail_mask(1:number_of_tails)
3579    tail_mask(number_of_tails+1:maximum_number_of_tails) = .TRUE.
3580
3581 END SUBROUTINE allocate_tail_memory
3582
3583
3584 SUBROUTINE output_particles_netcdf
3585#if defined( __netcdf )
3586
3587    USE control_parameters
3588    USE netcdf_control
3589    USE particle_attributes
3590
3591    IMPLICIT NONE
3592
3593
3594    CALL check_open( 108 )
3595
3596!
3597!-- Update the NetCDF time axis
3598    prt_time_count = prt_time_count + 1
3599
3600    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_time_prt, (/ simulated_time /), &
3601                            start = (/ prt_time_count /), count = (/ 1 /) )
3602    CALL handle_netcdf_error( 'output_particles_netcdf', 1 )
3603
3604!
3605!-- Output the real number of particles used
3606    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_rnop_prt, &
3607                            (/ number_of_particles /),   &
3608                            start = (/ prt_time_count /), count = (/ 1 /) )
3609    CALL handle_netcdf_error( 'output_particles_netcdf', 2 )
3610
3611!
3612!-- Output all particle attributes
3613    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(1), particles%age,         &
3614                            start = (/ 1, prt_time_count /),                  &
3615                            count = (/ maximum_number_of_particles /) )
3616    CALL handle_netcdf_error( 'output_particles_netcdf', 3 )
3617
3618    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(2), particles%dvrp_psize,  &
3619                            start = (/ 1, prt_time_count /),                  &
3620                            count = (/ maximum_number_of_particles /) )
3621    CALL handle_netcdf_error( 'output_particles_netcdf', 4 )
3622
3623    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(3), particles%origin_x,    &
3624                            start = (/ 1, prt_time_count /),                  &
3625                            count = (/ maximum_number_of_particles /) )
3626    CALL handle_netcdf_error( 'output_particles_netcdf', 5 )
3627
3628    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(4), particles%origin_y,    &
3629                            start = (/ 1, prt_time_count /),                  &
3630                            count = (/ maximum_number_of_particles /) )
3631    CALL handle_netcdf_error( 'output_particles_netcdf', 6 )
3632
3633    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(5), particles%origin_z,    &
3634                            start = (/ 1, prt_time_count /),                  &
3635                            count = (/ maximum_number_of_particles /) )
3636    CALL handle_netcdf_error( 'output_particles_netcdf', 7 )
3637
3638    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(6), particles%radius,      &
3639                            start = (/ 1, prt_time_count /),                  &
3640                            count = (/ maximum_number_of_particles /) )
3641    CALL handle_netcdf_error( 'output_particles_netcdf', 8 )
3642
3643    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(7), particles%speed_x,     &
3644                            start = (/ 1, prt_time_count /),                  &
3645                            count = (/ maximum_number_of_particles /) )
3646    CALL handle_netcdf_error( 'output_particles_netcdf', 9 )
3647
3648    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(8), particles%speed_y,     &
3649                            start = (/ 1, prt_time_count /),                  &
3650                            count = (/ maximum_number_of_particles /) )
3651    CALL handle_netcdf_error( 'output_particles_netcdf', 10 )
3652
3653    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(9), particles%speed_z,     &
3654                            start = (/ 1, prt_time_count /),                  &
3655                            count = (/ maximum_number_of_particles /) )
3656    CALL handle_netcdf_error( 'output_particles_netcdf', 11 )
3657
3658    nc_stat = NF90_PUT_VAR( id_set_prt,id_var_prt(10),particles%weight_factor,&
3659                            start = (/ 1, prt_time_count /),                  &
3660                            count = (/ maximum_number_of_particles /) )
3661    CALL handle_netcdf_error( 'output_particles_netcdf', 12 )
3662
3663    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(11), particles%x,           &
3664                            start = (/ 1, prt_time_count /),                  &
3665                            count = (/ maximum_number_of_particles /) )
3666    CALL handle_netcdf_error( 'output_particles_netcdf', 13 )
3667
3668    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(12), particles%y,          & 
3669                            start = (/ 1, prt_time_count /),                  &
3670                            count = (/ maximum_number_of_particles /) )
3671    CALL handle_netcdf_error( 'output_particles_netcdf', 14 )
3672
3673    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(13), particles%z,          &
3674                            start = (/ 1, prt_time_count /),                  &
3675                            count = (/ maximum_number_of_particles /) )
3676    CALL handle_netcdf_error( 'output_particles_netcdf', 15 )
3677
3678    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(14), particles%color,      &
3679                            start = (/ 1, prt_time_count /),                  &
3680                            count = (/ maximum_number_of_particles /) )
3681    CALL handle_netcdf_error( 'output_particles_netcdf', 16 )
3682
3683    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(15), particles%group,      &
3684                            start = (/ 1, prt_time_count /),                  &
3685                            count = (/ maximum_number_of_particles /) )
3686    CALL handle_netcdf_error( 'output_particles_netcdf', 17 )
3687
3688    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(16), particles%tailpoints, &
3689                            start = (/ 1, prt_time_count /),                  &
3690                            count = (/ maximum_number_of_particles /) )
3691    CALL handle_netcdf_error( 'output_particles_netcdf', 18 )
3692
3693    nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(17), particles%tail_id,    &
3694                            start = (/ 1, prt_time_count /),                  &
3695                            count = (/ maximum_number_of_particles /) )
3696    CALL handle_netcdf_error( 'output_particles_netcdf', 19 )
3697
3698#endif
3699 END SUBROUTINE output_particles_netcdf
3700
3701
3702 SUBROUTINE write_particles
3703
3704!------------------------------------------------------------------------------!
3705! Description:
3706! ------------
3707! Write particle data on restart file
3708!------------------------------------------------------------------------------!
3709
3710    USE control_parameters
3711    USE particle_attributes
3712    USE pegrid
3713
3714    IMPLICIT NONE
3715
3716    CHARACTER (LEN=10) ::  particle_binary_version
3717
3718!
3719!-- First open the output unit.
3720    IF ( myid_char == '' )  THEN
3721       OPEN ( 90, FILE='PARTICLE_RESTART_DATA_OUT'//myid_char, &
3722                  FORM='UNFORMATTED')
3723    ELSE
3724       IF ( myid == 0 )  CALL local_system( 'mkdir PARTICLE_RESTART_DATA_OUT' )
3725#if defined( __parallel )
3726!
3727!--    Set a barrier in order to allow that thereafter all other processors
3728!--    in the directory created by PE0 can open their file
3729       CALL MPI_BARRIER( comm2d, ierr )
3730#endif
3731       OPEN ( 90, FILE='PARTICLE_RESTART_DATA_OUT/'//myid_char, &
3732                  FORM='UNFORMATTED' )
3733    ENDIF
3734
3735!
3736!-- Write the version number of the binary format.
3737!-- Attention: After changes to the following output commands the version
3738!-- ---------  number of the variable particle_binary_version must be changed!
3739!--            Also, the version number and the list of arrays to be read in
3740!--            init_particles must be adjusted accordingly.
3741    particle_binary_version = '3.0'
3742    WRITE ( 90 )  particle_binary_version
3743
3744!
3745!-- Write some particle parameters, the size of the particle arrays as well as
3746!-- other dvrp-plot variables.
3747    WRITE ( 90 )  bc_par_b, bc_par_lr, bc_par_ns, bc_par_t,                    &
3748                  maximum_number_of_particles, maximum_number_of_tailpoints,   &
3749                  maximum_number_of_tails, number_of_initial_particles,        &
3750                  number_of_particles, number_of_particle_groups,              &
3751                  number_of_tails, particle_groups, time_prel,                 &
3752                  time_write_particle_data, uniform_particles
3753
3754    IF ( number_of_initial_particles /= 0 )  WRITE ( 90 )  initial_particles
3755
3756    WRITE ( 90 )  prt_count, prt_start_index
3757    WRITE ( 90 )  particles
3758
3759    IF ( use_particle_tails )  THEN
3760       WRITE ( 90 )  particle_tail_coordinates
3761    ENDIF
3762
3763    CLOSE ( 90 )
3764
3765 END SUBROUTINE write_particles
3766
3767
3768 SUBROUTINE collision_efficiency( mean_r, r, e)
3769!------------------------------------------------------------------------------!
3770! Description:
3771! ------------
3772! Interpolate collision efficiency from table
3773!------------------------------------------------------------------------------!
3774
3775    IMPLICIT NONE
3776
3777    INTEGER       ::  i, j, k
3778
3779    LOGICAL, SAVE ::  first = .TRUE.
3780
3781    REAL          ::  aa, bb, cc, dd, dx, dy, e, gg, mean_r, mean_rm, r, rm, &
3782                      x, y
3783
3784    REAL, DIMENSION(1:9), SAVE      ::  collected_r = 0.0
3785    REAL, DIMENSION(1:19), SAVE     ::  collector_r = 0.0
3786    REAL, DIMENSION(1:9,1:19), SAVE ::  ef = 0.0
3787
3788    mean_rm = mean_r * 1.0E06
3789    rm      = r      * 1.0E06
3790
3791    IF ( first )  THEN
3792       collected_r = (/ 2.0, 3.0, 4.0, 6.0, 8.0, 10.0, 15.0, 20.0, 25.0 /)
3793       collector_r = (/ 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 80.0, 100.0, 150.0,&
3794                        200.0, 300.0, 400.0, 500.0, 600.0, 1000.0, 1400.0,     &
3795                        1800.0, 2400.0, 3000.0 /)
3796       ef(:,1) = (/0.017, 0.027, 0.037, 0.052, 0.052, 0.052, 0.052, 0.0,  0.0 /)
3797       ef(:,2) = (/0.001, 0.016, 0.027, 0.060, 0.12,  0.17,  0.17,  0.17, 0.0 /)
3798       ef(:,3) = (/0.001, 0.001, 0.02,  0.13,  0.28,  0.37,  0.54,  0.55, 0.47/)
3799       ef(:,4) = (/0.001, 0.001, 0.02,  0.23,  0.4,   0.55,  0.7,   0.75, 0.75/)
3800       ef(:,5) = (/0.01,  0.01,  0.03,  0.3,   0.4,   0.58,  0.73,  0.75, 0.79/)
3801       ef(:,6) = (/0.01,  0.01,  0.13,  0.38,  0.57,  0.68,  0.80,  0.86, 0.91/)
3802       ef(:,7) = (/0.01,  0.085, 0.23,  0.52,  0.68,  0.76,  0.86,  0.92, 0.95/)
3803       ef(:,8) = (/0.01,  0.14,  0.32,  0.60,  0.73,  0.81,  0.90,  0.94, 0.96/)
3804       ef(:,9) = (/0.025, 0.25,  0.43,  0.66,  0.78,  0.83,  0.92,  0.95, 0.96/)
3805       ef(:,10)= (/0.039, 0.3,   0.46,  0.69,  0.81,  0.87,  0.93,  0.95, 0.96/)
3806       ef(:,11)= (/0.095, 0.33,  0.51,  0.72,  0.82,  0.87,  0.93,  0.96, 0.97/)
3807       ef(:,12)= (/0.098, 0.36,  0.51,  0.73,  0.83,  0.88,  0.93,  0.96, 0.97/)
3808       ef(:,13)= (/0.1,   0.36,  0.52,  0.74,  0.83,  0.88,  0.93,  0.96, 0.97/)
3809       ef(:,14)= (/0.17,  0.4,   0.54,  0.72,  0.83,  0.88,  0.94,  0.98, 1.0 /)
3810       ef(:,15)= (/0.15,  0.37,  0.52,  0.74,  0.82,  0.88,  0.94,  0.98, 1.0 /)
3811       ef(:,16)= (/0.11,  0.34,  0.49,  0.71,  0.83,  0.88,  0.94,  0.95, 1.0 /)
3812       ef(:,17)= (/0.08,  0.29,  0.45,  0.68,  0.8,   0.86,  0.96,  0.94, 1.0 /)
3813       ef(:,18)= (/0.04,  0.22,  0.39,  0.62,  0.75,  0.83,  0.92,  0.96, 1.0 /)
3814       ef(:,19)= (/0.02,  0.16,  0.33,  0.55,  0.71,  0.81,  0.90,  0.94, 1.0 /)
3815    ENDIF
3816
3817    DO  k = 1, 8
3818       IF ( collected_r(k) <= mean_rm )  i = k
3819    ENDDO
3820
3821    DO  k = 1, 18
3822       IF ( collector_r(k) <= rm )  j = k
3823    ENDDO
3824
3825    IF ( rm < 10.0 )  THEN
3826       e = 0.0
3827    ELSEIF ( mean_rm < 2.0 )  THEN
3828       e = 0.001
3829    ELSEIF ( mean_rm >= 25.0 )  THEN
3830       IF( j <= 3 )  e = 0.55
3831       IF( j == 4 )  e = 0.8
3832       IF( j == 5 )  e = 0.9
3833       IF( j >=6  )  e = 1.0
3834    ELSEIF ( rm >= 3000.0 )  THEN
3835       e = 1.0
3836    ELSE
3837       x  = mean_rm - collected_r(i)
3838       y  = rm - collected_r(j)
3839       dx = collected_r(i+1) - collected_r(i) 
3840       dy = collector_r(j+1) - collector_r(j) 
3841       aa = x**2 + y**2
3842       bb = ( dx - x )**2 + y**2
3843       cc = x**2 + ( dy - y )**2
3844       dd = ( dx - x )**2 + ( dy - y )**2
3845       gg = aa + bb + cc + dd
3846
3847       e = ( (gg-aa)*ef(i,j) + (gg-bb)*ef(i+1,j) + (gg-cc)*ef(i,j+1) + &
3848             (gg-dd)*ef(i+1,j+1) ) / (3.0*gg)
3849    ENDIF
3850
3851 END SUBROUTINE collision_efficiency 
3852
3853
3854
3855 SUBROUTINE sort_particles
3856
3857!------------------------------------------------------------------------------!
3858! Description:
3859! ------------
3860! Sort particles in the sequence the grid boxes are stored in memory
3861!------------------------------------------------------------------------------!
3862
3863    USE arrays_3d
3864    USE control_parameters
3865    USE cpulog
3866    USE grid_variables
3867    USE indices
3868    USE interfaces
3869    USE particle_attributes
3870
3871    IMPLICIT NONE
3872
3873    INTEGER ::  i, ilow, j, k, n
3874
3875    TYPE(particle_type), DIMENSION(1:number_of_particles) ::  particles_temp
3876
3877
3878    CALL cpu_log( log_point_s(47), 'sort_particles', 'start' )
3879
3880!
3881!-- Initialize the array used for counting and indexing the particles
3882    prt_count = 0
3883
3884!
3885!-- Count the particles per gridbox
3886    DO  n = 1, number_of_particles
3887
3888       i = ( particles(n)%x + 0.5 * dx ) * ddx
3889       j = ( particles(n)%y + 0.5 * dy ) * ddy
3890       k = particles(n)%z / dz + 1 + offset_ocean_nzt
3891           ! only exact if equidistant
3892
3893       prt_count(k,j,i) = prt_count(k,j,i) + 1
3894
3895       IF ( i < nxl .OR. i > nxr .OR. j < nys .OR. j > nyn .OR. k < nzb+1 .OR. &
3896            k > nzt )  THEN
3897          WRITE( message_string, * ) ' particle out of range: i=', i, ' j=', &
3898                          j, ' k=', k, &
3899                          ' &nxl=', nxl, ' nxr=', nxr, &
3900                          ' nys=', nys, ' nyn=', nyn, &
3901                          ' nzb=', nzb, ' nzt=', nzt
3902         CALL message( 'sort_particles', 'PA0149', 1, 2, 0, 6, 0 ) 
3903       ENDIF
3904
3905    ENDDO
3906
3907!
3908!-- Calculate the lower indices of those ranges of the particles-array
3909!-- containing particles which belong to the same gridpox i,j,k
3910    ilow = 1
3911    DO  i = nxl, nxr
3912       DO  j = nys, nyn
3913          DO  k = nzb+1, nzt
3914             prt_start_index(k,j,i) = ilow
3915             ilow = ilow + prt_count(k,j,i)
3916          ENDDO
3917       ENDDO
3918    ENDDO
3919
3920!
3921!-- Sorting the particles
3922    DO  n = 1, number_of_particles
3923
3924       i = ( particles(n)%x + 0.5 * dx ) * ddx
3925       j = ( particles(n)%y + 0.5 * dy ) * ddy
3926       k = particles(n)%z / dz + 1 + offset_ocean_nzt
3927           ! only exact if equidistant
3928
3929       particles_temp(prt_start_index(k,j,i)) = particles(n)
3930
3931       prt_start_index(k,j,i) = prt_start_index(k,j,i) + 1
3932
3933    ENDDO
3934
3935    particles(1:number_of_particles) = particles_temp
3936
3937!
3938!-- Reset the index array to the actual start position
3939    DO  i = nxl, nxr
3940       DO  j = nys, nyn
3941          DO  k = nzb+1, nzt
3942             prt_start_index(k,j,i) = prt_start_index(k,j,i) - prt_count(k,j,i)
3943          ENDDO
3944       ENDDO
3945    ENDDO
3946
3947    CALL cpu_log( log_point_s(47), 'sort_particles', 'stop' )
3948
3949 END SUBROUTINE sort_particles
Note: See TracBrowser for help on using the repository browser.