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

Last change on this file since 2 was 1, checked in by raasch, 17 years ago

Initial repository layout and content

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