Index: palm/trunk/SOURCE/lpm.f90
===================================================================
--- palm/trunk/SOURCE/lpm.f90	(revision 1321)
+++ palm/trunk/SOURCE/lpm.f90	(revision 1359)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! ------------------
-!
+! New particle structure integrated. 
+! Kind definition added to all floating point numbers.
 !
 ! Former revisions:
@@ -82,21 +83,30 @@
     USE control_parameters,                                                    &
         ONLY:  cloud_droplets, dt_3d, dt_3d_reached, dt_3d_reached_l,          &
-               molecular_viscosity, simulated_time
+               molecular_viscosity, simulated_time, topography
 
     USE cpulog,                                                                &
         ONLY:  cpu_log, log_point, log_point_s
 
+    USE indices,                                                               &
+        ONLY: nxl, nxr, nys, nyn, nzb, nzt
+
     USE kinds
 
+    USE lpm_exchange_horiz_mod,                                                &
+        ONLY:  lpm_exchange_horiz, lpm_move_particle
+
+    USE lpm_pack_arrays_mod,                                                   &
+        ONLY:  lpm_pack_all_arrays
+
     USE particle_attributes,                                                   &
-        ONLY:  collision_kernel, deleted_particles, dt_sort_particles,         &
-               deleted_tails, dt_write_particle_data, dt_prel, end_time_prel,  &
-               number_of_particles, number_of_particle_groups,particles,       &
-               particle_groups, particle_mask, trlp_count_sum, tail_mask,      &
-               time_prel, time_sort_particles, time_write_particle_data,       &
-               trlp_count_recv_sum, trnp_count_sum, trnp_count_recv_sum,       &
-               trrp_count_sum, trrp_count_recv_sum, trsp_count_sum,            &
-               trsp_count_recv_sum, use_particle_tails, use_sgs_for_particles, &
-               write_particle_statistics
+        ONLY:  collision_kernel, deleted_particles, deleted_tails,             &
+               dt_write_particle_data, dt_prel, end_time_prel,                 &
+               grid_particles, number_of_particles, number_of_particle_groups, &
+               particles, particle_groups, prt_count, trlp_count_sum,          &
+               tail_mask, time_prel, time_sort_particles,                      &
+               time_write_particle_data, trlp_count_recv_sum, trnp_count_sum,  &
+               trnp_count_recv_sum, trrp_count_sum, trrp_count_recv_sum,       &
+               trsp_count_sum, trsp_count_recv_sum, use_particle_tails,        &
+               use_sgs_for_particles, write_particle_statistics
 
     USE pegrid
@@ -104,6 +114,17 @@
     IMPLICIT NONE
 
-    INTEGER(iwp) ::  m                       !:
-
+    INTEGER(iwp)       ::  i                  !:
+    INTEGER(iwp)       ::  ie                 !:
+    INTEGER(iwp)       ::  is                 !:
+    INTEGER(iwp)       ::  j                  !:
+    INTEGER(iwp)       ::  je                 !:
+    INTEGER(iwp)       ::  js                 !:
+    INTEGER(iwp)       ::  k                  !:
+    INTEGER(iwp)       ::  ke                 !:
+    INTEGER(iwp)       ::  ks                 !:
+    INTEGER(iwp)       ::  m                  !:
+    INTEGER(iwp), SAVE ::  steps = 0          !:
+
+    LOGICAL            ::  first_loop_stride  !:
 
     CALL cpu_log( log_point(25), 'lpm', 'start' )
@@ -125,9 +146,7 @@
     ENDIF
 
-
 !
 !-- Initialize arrays for marking those particles/tails to be deleted after the
 !-- (sub-) timestep
-    particle_mask     = .TRUE.
     deleted_particles = 0
 
@@ -157,46 +176,35 @@
 !-- of the particle groups
     DO  m = 1, number_of_particle_groups
-       IF ( particle_groups(m)%density_ratio /= 0.0 )  THEN
+       IF ( particle_groups(m)%density_ratio /= 0.0_wp )  THEN
           particle_groups(m)%exp_arg  =                                        &
-                    4.5 * particle_groups(m)%density_ratio *                   &
+                    4.5_wp * particle_groups(m)%density_ratio *                &
                     molecular_viscosity / ( particle_groups(m)%radius )**2
-          particle_groups(m)%exp_term = EXP( -particle_groups(m)%exp_arg * &
-                                             dt_3d )
+
+          particle_groups(m)%exp_term = EXP( -particle_groups(m)%exp_arg *     &
+                    dt_3d )
        ENDIF
     ENDDO
 
-
-!
-!-- Particle (droplet) growth by condensation/evaporation and collision
-    IF ( cloud_droplets )  THEN
-
-!
-!--    Reset summation arrays
-       ql_c = 0.0;  ql_v = 0.0;  ql_vp = 0.0
-
-!
-!--    Droplet growth by condensation / evaporation
-       CALL lpm_droplet_condensation
-
-!
-!--    Particle growth by collision
-       IF ( collision_kernel /= 'none' )  CALL lpm_droplet_collision
-
-    ENDIF
-
-
-!
-!-- If particle advection includes SGS velocity components, calculate the
-!-- required SGS quantities (i.e. gradients of the TKE, as well as horizontally
-!-- averaged profiles of the SGS TKE and the resolved-scale velocity variances)
-    IF ( use_sgs_for_particles )  CALL lpm_init_sgs_tke
-
-
-!
-!-- Initialize the variable storing the total time that a particle has advanced
-!-- within the timestep procedure
-    particles(1:number_of_particles)%dt_sum = 0.0
-
-
+!
+!-- If necessary, release new set of particles
+    IF ( time_prel >= dt_prel  .AND.  end_time_prel > simulated_time )  THEN
+
+       CALL lpm_release_set
+!
+!--    The MOD function allows for changes in the output interval with
+!--    restart runs.
+       time_prel = MOD( time_prel, MAX( dt_prel, dt_3d ) )
+
+    ENDIF
+!
+!-- Reset summation arrays
+    IF ( cloud_droplets)  THEN
+       ql_c  = 0.0_wp
+       ql_v  = 0.0_wp
+       ql_vp = 0.0_wp
+    ENDIF
+
+    first_loop_stride = .TRUE.
+    grid_particles(:,:,:)%time_loop_done = .TRUE.
 !
 !-- Timestep loop for particle advection.
@@ -204,31 +212,103 @@
 !-- (within the total domain!) has reached the LES timestep (dt_3d).
 !-- In case of including the SGS velocities, the particle timestep may be
-!-- smaller than the LES timestep (because of the Lagrangian timescale restric-
-!-- tion) and particles may require to undergo several particle timesteps,
-!-- before the LES timestep is reached. Because the number of these particle
-!-- timesteps to be carried out is unknown at first, these steps are carried
-!-- out in the following infinite loop with exit condition.
+!-- smaller than the LES timestep (because of the Lagrangian timescale 
+!-- restriction) and particles may require to undergo several particle 
+!-- timesteps, before the LES timestep is reached. Because the number of these 
+!-- particle timesteps to be carried out is unknown at first, these steps are 
+!-- carried out in the following infinite loop with exit condition.
     DO
-
        CALL cpu_log( log_point_s(44), 'lpm_advec', 'start' )
-
-!
-!--    Initialize the switch used for the loop exit condition checked at the
-!--    end of this loop.
-!--    If at least one particle has failed to reach the LES timestep, this
-!--    switch will be set false.
-       dt_3d_reached_l = .TRUE.
-
-!
-!--    Particle advection
-       CALL lpm_advec
-
-!
-!--    Particle reflection from walls
-       CALL lpm_boundary_conds( 'walls' )
-
-!
-!--    User-defined actions after the calculation of the new particle position
-       CALL user_lpm_advec
+       CALL cpu_log( log_point_s(44), 'lpm_advec', 'pause' )
+!
+!--    If particle advection includes SGS velocity components, calculate the
+!--    required SGS quantities (i.e. gradients of the TKE, as well as 
+!--    horizontally averaged profiles of the SGS TKE and the resolved-scale 
+!--    velocity variances)
+
+       IF ( use_sgs_for_particles )  CALL lpm_init_sgs_tke
+
+       DO  i = nxl, nxr
+          DO  j = nys, nyn
+             DO  k = nzb+1, nzt
+
+                number_of_particles = prt_count(k,j,i)
+!
+!--             If grid cell gets empty, flag must be true
+                IF ( number_of_particles <= 0 )  THEN
+                   grid_particles(k,j,i)%time_loop_done = .TRUE.
+                   CYCLE
+                ENDIF
+
+                IF ( .NOT. first_loop_stride  .AND.  &
+                     grid_particles(k,j,i)%time_loop_done ) CYCLE
+
+                particles => grid_particles(k,j,i)%particles(1:number_of_particles)
+
+                particles(1:number_of_particles)%particle_mask = .TRUE.
+!
+!--             Initialize the variable storing the total time that a particle 
+!--             has advanced within the timestep procedure
+                IF ( first_loop_stride )  THEN
+                   particles(1:number_of_particles)%dt_sum = 0.0_wp
+                ENDIF
+!
+!--             Particle (droplet) growth by condensation/evaporation and 
+!--             collision
+                IF ( cloud_droplets  .AND.  first_loop_stride)  THEN
+!
+!--                Droplet growth by condensation / evaporation
+                   CALL lpm_droplet_condensation(i,j,k)
+!
+!--                Particle growth by collision
+                   IF ( collision_kernel /= 'none' )  THEN
+                      CALL lpm_droplet_collision(i,j,k)
+                   ENDIF
+
+                ENDIF
+!
+!--             Initialize the switch used for the loop exit condition checked
+!--             at the end of this loop. If at least one particle has failed to
+!--             reach the LES timestep, this switch will be set false in 
+!--             lpm_advec.
+                dt_3d_reached_l = .TRUE.
+
+!
+!--             Particle advection
+                CALL lpm_advec(i,j,k)
+!
+!--             Particle reflection from walls
+                IF ( topography /= 'flat' )  THEN
+                   CALL lpm_boundary_conds( 'walls' )
+                ENDIF
+!
+!--             User-defined actions after the calculation of the new particle 
+!--             position
+                CALL user_lpm_advec
+!
+!--             Apply boundary conditions to those particles that have crossed 
+!--             the top or bottom boundary and delete those particles, which are
+!--             older than allowed
+                CALL lpm_boundary_conds( 'bottom/top' )
+!
+!---            If not all particles of the actual grid cell have reached the 
+!--             LES timestep, this cell has to to another loop iteration. Due to
+!--             the fact that particles can move into neighboring grid cell, 
+!--             these neighbor cells also have to perform another loop iteration
+                IF ( .NOT. dt_3d_reached_l )  THEN
+                   ks = MAX(nzb+1,k)
+                   ke = MIN(nzt,k)
+                   js = MAX(nys,j)
+                   je = MIN(nyn,j)
+                   is = MAX(nxl,i)
+                   ie = MIN(nxr,i)
+                   grid_particles(ks:ke,js:je,is:ie)%time_loop_done = .FALSE.
+                ENDIF
+
+             ENDDO
+          ENDDO
+       ENDDO
+
+       steps = steps + 1
+       dt_3d_reached_l = ALL(grid_particles(:,:,:)%time_loop_done)
 
 !
@@ -250,16 +330,6 @@
 
 !
-!--    If necessary, release new set of particles
-       IF ( time_prel >= dt_prel  .AND.  end_time_prel > simulated_time  .AND. &
-            dt_3d_reached )  THEN
-
-          CALL lpm_release_set
-
-!
-!--       The MOD function allows for changes in the output interval with
-!--       restart runs.
-          time_prel = MOD( time_prel, MAX( dt_prel, dt_3d ) )
-
-       ENDIF
+!--    Move Particles local to PE to a different grid cell
+       CALL lpm_move_particle
 
 !
@@ -268,19 +338,11 @@
 
 !
-!--    Apply boundary conditions to those particles that have crossed the top or
-!--    bottom boundary and delete those particles, which are older than allowed
-       CALL lpm_boundary_conds( 'bottom/top' )
-
-!
 !--    Pack particles (eliminate those marked for deletion),
 !--    determine new number of particles
-       IF ( number_of_particles > 0  .AND.  deleted_particles > 0 )  THEN
-          CALL lpm_pack_arrays
-       ENDIF
-
-!
-!--    Initialize variables for the next (sub-) timestep, i.e. for marking those
-!--    particles to be deleted after the timestep
-       particle_mask     = .TRUE.
+       CALL lpm_pack_all_arrays
+
+!
+!--    Initialize variables for the next (sub-) timestep, i.e., for marking 
+!--    those particles to be deleted after the timestep
        deleted_particles = 0
 
@@ -293,20 +355,13 @@
        IF ( dt_3d_reached )  EXIT
 
+       first_loop_stride = .FALSE.
     ENDDO   ! timestep loop
 
-
-!
-!-- Sort particles in the sequence the gridboxes are stored in the memory
-    time_sort_particles = time_sort_particles + dt_3d
-    IF ( time_sort_particles >= dt_sort_particles )  THEN
-       CALL lpm_sort_arrays
-       time_sort_particles = MOD( time_sort_particles, &
-                                  MAX( dt_sort_particles, dt_3d ) )
-    ENDIF
-
-
 !
 !-- Calculate the new liquid water content for each grid box
-    IF ( cloud_droplets )  CALL lpm_calc_liquid_water_content
+    IF ( cloud_droplets )  THEN
+       CALL lpm_calc_liquid_water_content
+    ENDIF
+
 
 
@@ -325,6 +380,8 @@
 
 !
+!-- particle tails currently not available
+!
 !-- If required, add the current particle positions to the particle tails
-    IF ( use_particle_tails )  CALL lpm_extend_tails
+!   IF ( use_particle_tails )  CALL lpm_extend_tails
 
 
@@ -336,4 +393,3 @@
     CALL cpu_log( log_point(25), 'lpm', 'stop' )
 
-
  END SUBROUTINE lpm
