Index: palm/trunk/SOURCE/lagrangian_particle_model_mod.f90
===================================================================
--- palm/trunk/SOURCE/lagrangian_particle_model_mod.f90	(revision 4616)
+++ palm/trunk/SOURCE/lagrangian_particle_model_mod.f90	(revision 4628)
@@ -25,4 +25,7 @@
 ! -----------------
 ! $Id$
+! extensions required for MPI-I/O of particle data to restart files
+!
+! 4616 2020-07-21 10:09:46Z schwenkel
 ! Bugfix in case of strechting: k-calculation limited lower bound of 1
 ! 
@@ -189,9 +192,10 @@
                child_domain,                                                   &
                cloud_droplets, constant_flux_layer, current_timestep_number,   &
-               dt_3d, dt_3d_reached, first_call_lpm, humidity,                 &
+               dt_3d, dt_3d_reached, debug_output, first_call_lpm, humidity,   &
                dt_3d_reached_l, dt_dopts, dz, initializing_actions,            &
                intermediate_timestep_count, intermediate_timestep_count_max,   &
                message_string, molecular_viscosity, ocean_mode,                &
-               particle_maximum_age, restart_data_format_output,               &
+               particle_maximum_age, restart_data_format_input,                &
+               restart_data_format_output,                                     &
                simulated_time, topography, dopts_time_count,                   &
                time_since_reference_point, rho_surface, u_gtrans, v_gtrans,    &
@@ -240,6 +244,16 @@
                id_random_array
 
-    USE restart_data_mpi_io_mod,                                                                   &
-        ONLY:  rd_mpi_io_check_array, rrd_mpi_io, wrd_mpi_io
+    USE restart_data_mpi_io_mod,                                               &
+        ONLY:  rd_mpi_io_check_array,                                          &
+               rd_mpi_io_check_open,                                           &
+               rd_mpi_io_close,                                                &
+               rd_mpi_io_open,                                                 &
+               rd_mpi_io_particle_filetypes,                                   &
+               rrd_mpi_io,                                                     &
+               rrd_mpi_io_global_array,                                        &
+               rrd_mpi_io_particles,                                           &
+               wrd_mpi_io,                                                     &
+               wrd_mpi_io_global_array,                                        &
+               wrd_mpi_io_particles
 
     USE statistics,                                                            &
@@ -251,4 +265,8 @@
                surf_lsm_h,                                                     &
                surf_usm_h
+
+!-- Next lines are in preparation for the output of particle data
+!    USE data_output_particle_mod,                                              &
+!        ONLY:  dop_active, dop_init, dop_output_tseries
 
 #if defined( __parallel )  &&  !defined( __mpifh )
@@ -594,5 +612,5 @@
        write_particle_statistics
 
-       NAMELIST /particle_parameters/ &
+    NAMELIST /particle_parameters/ &
        aero_species, &
        aero_type, &
@@ -619,10 +637,15 @@
        na, &
        number_concentration, &
+       number_of_output_particles, &
        number_of_particle_groups, &
        number_particles_per_gridbox, &
+       oversize, &
        particles_per_point, &
        particle_advection_start, &
        particle_advection_interpolation, &
        particle_maximum_age, &
+       part_output, &
+       part_inc, &
+       part_percent, &
        pdx, &
        pdy, &
@@ -648,4 +671,5 @@
        splitting_mode, &
        step_dealloc, &
+       unlimited_dimension, &
        use_sgs_for_particles, &
        vertical_particle_advection, &
@@ -1215,4 +1239,5 @@
 !-- Initialize collision kernels
     IF ( collision_kernel /= 'none' )  CALL lpm_init_kernels
+
 !
 !-- For the first model run of a possible job chain initialize the
@@ -1241,5 +1266,5 @@
                                       0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp,  &
                                       0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp,  &
-                                      0, 0, 0_idp, .FALSE., -1 )
+                                      0, 0, 0_idp, .FALSE., -1, -1 )
 
        particle_groups = particle_groups_type( 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp )
@@ -1304,4 +1329,7 @@
     IF ( nested_run )  CALL pmcp_g_init
 #endif
+
+!-- next line is in preparation for particle data output
+!    CALL dop_init
 
 !
@@ -2995,6 +3023,8 @@
  SUBROUTINE lpm_rrd_local_particles
 
-    CHARACTER (LEN=10) ::  particle_binary_version    !<
-    CHARACTER (LEN=10) ::  version_on_file            !<
+    CHARACTER(LEN=10) ::  particle_binary_version    !<
+    CHARACTER(LEN=10) ::  version_on_file            !<
+
+    CHARACTER(LEN=20) ::  save_restart_data_format_input  !<
 
     INTEGER(iwp) ::  alloc_size !<
@@ -3003,89 +3033,157 @@
     INTEGER(iwp) ::  kp         !<
 
+    INTEGER(idp), ALLOCATABLE, DIMENSION(:,:,:) ::  prt_global_index !<
+
+    LOGICAL ::  save_debug_output  !<
+
     TYPE(particle_type), DIMENSION(:), ALLOCATABLE ::  tmp_particles !<
 
-!
-!-- Read particle data from previous model run.
-!-- First open the input unit.
-    IF ( myid_char == '' )  THEN
-       OPEN ( 90, FILE='PARTICLE_RESTART_DATA_IN'//myid_char,                  &
-                  FORM='UNFORMATTED' )
-    ELSE
-       OPEN ( 90, FILE='PARTICLE_RESTART_DATA_IN/'//myid_char,                 &
-                  FORM='UNFORMATTED' )
-    ENDIF
-
-!
-!-- First compare the version numbers
-    READ ( 90 )  version_on_file
-    particle_binary_version = '4.0'
-    IF ( TRIM( version_on_file ) /= TRIM( particle_binary_version ) )  THEN
-       message_string = 'version mismatch concerning data from prior ' //      &
-                        'run &version on file = "' //                          &
-                                      TRIM( version_on_file ) //               &
-                        '&version in program = "' //                           &
-                                      TRIM( particle_binary_version ) // '"'
-       CALL message( 'lpm_read_restart_file', 'PA0214', 1, 2, 0, 6, 0 )
-    ENDIF
-
-!
-!-- If less particles are stored on the restart file than prescribed by
-!-- 1, the remainder is initialized by zero_particle to avoid
-!-- errors.
-    zero_particle = particle_type( 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp,     &
-                                   0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp,     &
-                                   0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp,     &
-                                   0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp,     &
-                                   0, 0, 0_idp, .FALSE., -1 )
-!
-!-- Read some particle parameters and the size of the particle arrays,
-!-- allocate them and read their contents.
-    READ ( 90 )  bc_par_b, bc_par_lr, bc_par_ns, bc_par_t,                     &
-                 last_particle_release_time, number_of_particle_groups,        &
-                 particle_groups, time_write_particle_data
-
-    ALLOCATE( prt_count(nzb:nzt+1,nysg:nyng,nxlg:nxrg),                        &
-              grid_particles(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
-
-    READ ( 90 )  prt_count
-
-    DO  ip = nxl, nxr
-       DO  jp = nys, nyn
-          DO  kp = nzb+1, nzt
-
-             number_of_particles = prt_count(kp,jp,ip)
-             IF ( number_of_particles > 0 )  THEN
-                alloc_size = MAX( INT( number_of_particles *                   &
-                             ( 1.0_wp + alloc_factor / 100.0_wp ) ),           &
-                             1 )
-             ELSE
-                alloc_size = 1
-             ENDIF
-
-             ALLOCATE( grid_particles(kp,jp,ip)%particles(1:alloc_size) )
-
-             IF ( number_of_particles > 0 )  THEN
-                ALLOCATE( tmp_particles(1:number_of_particles) )
-                READ ( 90 )  tmp_particles
-                grid_particles(kp,jp,ip)%particles(1:number_of_particles) = tmp_particles
-                DEALLOCATE( tmp_particles )
-                IF ( number_of_particles < alloc_size )  THEN
-                   grid_particles(kp,jp,ip)%particles(number_of_particles+1:alloc_size) &
-                      = zero_particle
+    IF ( TRIM( restart_data_format_input ) == 'fortran_binary' )  THEN
+
+!
+!--    Read particle data from previous model run.
+!--    First open the input unit.
+       IF ( myid_char == '' )  THEN
+          OPEN ( 90, FILE='PARTICLE_RESTART_DATA_IN'//myid_char,                  &
+                     FORM='UNFORMATTED' )
+       ELSE
+          OPEN ( 90, FILE='PARTICLE_RESTART_DATA_IN/'//myid_char,                 &
+                     FORM='UNFORMATTED' )
+       ENDIF
+
+!
+!--    First compare the version numbers
+       READ ( 90 )  version_on_file
+       particle_binary_version = '4.0'
+       IF ( TRIM( version_on_file ) /= TRIM( particle_binary_version ) )  THEN
+          message_string = 'version mismatch concerning data from prior ' //      &
+                           'run &version on file = "' //                          &
+                                         TRIM( version_on_file ) //               &
+                           '&version in program = "' //                           &
+                                         TRIM( particle_binary_version ) // '"'
+          CALL message( 'lpm_read_restart_file', 'PA0214', 1, 2, 0, 6, 0 )
+       ENDIF
+
+!
+!--    If less particles are stored on the restart file than prescribed by
+!--    1, the remainder is initialized by zero_particle to avoid
+!--    errors.
+       zero_particle = particle_type( 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp,     &
+                                      0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp,     &
+                                      0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp,     &
+                                      0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp,     &
+                                      0, 0, 0_idp, .FALSE., -1, -1 )
+!
+!--    Read some particle parameters and the size of the particle arrays,
+!--    allocate them and read their contents.
+       READ ( 90 )  bc_par_b, bc_par_lr, bc_par_ns, bc_par_t,                     &
+                    last_particle_release_time, number_of_particle_groups,        &
+                    particle_groups, time_write_particle_data
+
+       ALLOCATE( prt_count(nzb:nzt+1,nysg:nyng,nxlg:nxrg),                        &
+                 grid_particles(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
+
+       READ ( 90 )  prt_count
+
+       DO  ip = nxl, nxr
+          DO  jp = nys, nyn
+             DO  kp = nzb+1, nzt
+
+                number_of_particles = prt_count(kp,jp,ip)
+                IF ( number_of_particles > 0 )  THEN
+                   alloc_size = MAX( INT( number_of_particles *                   &
+                                ( 1.0_wp + alloc_factor / 100.0_wp ) ),           &
+                                1 )
+                ELSE
+                   alloc_size = 1
                 ENDIF
-             ELSE
-                grid_particles(kp,jp,ip)%particles(1:alloc_size) = zero_particle
-             ENDIF
-
+
+                ALLOCATE( grid_particles(kp,jp,ip)%particles(1:alloc_size) )
+
+                IF ( number_of_particles > 0 )  THEN
+                   ALLOCATE( tmp_particles(1:number_of_particles) )
+                   READ ( 90 )  tmp_particles
+                   grid_particles(kp,jp,ip)%particles(1:number_of_particles) = tmp_particles
+                   DEALLOCATE( tmp_particles )
+                   IF ( number_of_particles < alloc_size )  THEN
+                      grid_particles(kp,jp,ip)%particles(number_of_particles+1:alloc_size) &
+                         = zero_particle
+                   ENDIF
+                ELSE
+                   grid_particles(kp,jp,ip)%particles(1:alloc_size) = zero_particle
+                ENDIF
+
+             ENDDO
           ENDDO
        ENDDO
-    ENDDO
-
-    CLOSE ( 90 )
+
+       CLOSE ( 90 )
+
+    ELSEIF ( restart_data_format_input(1:3) == 'mpi' )  THEN
+
+       WRITE ( 9, * )  'Here is MPI-IO praticle input ', rd_mpi_io_check_open()
+       FLUSH(9)
+
+       ALLOCATE( prt_count(nzb:nzt+1,nysg:nyng,nxlg:nxrg),                        &
+                 grid_particles(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
+
+       ALLOCATE( prt_global_index(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
+!
+!--    Open restart file for read, if not already open, and do not allow usage of
+!--    shared-memory I/O
+       IF ( .NOT. rd_mpi_io_check_open() )  THEN
+          save_restart_data_format_input = restart_data_format_input
+          restart_data_format_input = 'mpi'
+          CALL rd_mpi_io_open( 'READ', 'BININ' )
+          restart_data_format_input = save_restart_data_format_input
+       ENDIF
+
+       CALL  rd_mpi_io_particle_filetypes
+
+       prt_count = 0
+       CALL rrd_mpi_io( 'prt_count', prt_count )
+       CALL rrd_mpi_io( 'prt_global_index', prt_global_index )
+
+!
+!--    Allocate particles arrays
+       DO  ip = nxl, nxr
+          DO  jp = nys, nyn
+             DO  kp = nzb+1, nzt
+
+                number_of_particles = prt_count(kp,jp,ip)
+                IF ( number_of_particles > 0 )  THEN
+                   alloc_size = MAX( INT( number_of_particles *                   &
+                      ( 1.0_wp + alloc_factor / 100.0_wp ) ),           &
+                      1 )
+                ELSE
+                   alloc_size = 1
+                ENDIF
+
+                ALLOCATE( grid_particles(kp,jp,ip)%particles(1:alloc_size) )
+
+             ENDDO
+          ENDDO
+       ENDDO
+
+!
+!--    Now read particle data from restart file
+       CALL rrd_mpi_io_particles( 'particles', prt_global_index )
+
+       IF ( .NOT. rd_mpi_io_check_open() )  THEN
+!
+!--       Do not print header a second time to the debug file
+          save_debug_output = debug_output
+          debug_output      = .FALSE.
+          CALL rd_mpi_io_close()
+          debug_output = save_debug_output
+       ENDIF
+
+       DEALLOCATE( prt_global_index )
+
+    ENDIF
 !
 !-- Must be called to sort particles into blocks, which is needed for a fast
 !-- interpolation of the LES fields on the particle position.
     CALL lpm_sort_and_delete
-
 
  END SUBROUTINE lpm_rrd_local_particles
@@ -3256,57 +3354,73 @@
  
     CHARACTER (LEN=10) ::  particle_binary_version   !<
-    CHARACTER (LEN=20) ::  tmp_name                  !< temporary variable
+    CHARACTER (LEN=32) ::  tmp_name                  !< temporary variable
 
     INTEGER(iwp) ::  i                               !< loop index
     INTEGER(iwp) ::  ip                              !<
+    INTEGER(iwp) ::  j                               !< loop index
     INTEGER(iwp) ::  jp                              !<
+    INTEGER(iwp) ::  k                               !< loop index
     INTEGER(iwp) ::  kp                              !< 
-!
-!-- First open the output unit.
-    IF ( myid_char == '' )  THEN
-       OPEN ( 90, FILE='PARTICLE_RESTART_DATA_OUT'//myid_char, &
-                  FORM='UNFORMATTED')
-    ELSE
-       IF ( myid == 0 )  CALL local_system( 'mkdir PARTICLE_RESTART_DATA_OUT' )
+
 #if defined( __parallel )
-!
-!--    Set a barrier in order to allow that thereafter all other processors
-!--    in the directory created by PE0 can open their file
-       CALL MPI_BARRIER( comm2d, ierr )
+    INTEGER      :: ierr                             !<
 #endif
-       OPEN ( 90, FILE='PARTICLE_RESTART_DATA_OUT/'//myid_char, &
-                  FORM='UNFORMATTED' )
-    ENDIF
-
-!
-!-- Write the version number of the binary format.
-!-- Attention: After changes to the following output commands the version
-!-- ---------  number of the variable particle_binary_version must be
-!--            changed! Also, the version number and the list of arrays
-!--            to be read in lpm_read_restart_file must be adjusted
-!--            accordingly.
-    particle_binary_version = '4.0'
-    WRITE ( 90 )  particle_binary_version
-
-!
-!-- Write some particle parameters, the size of the particle arrays
-    WRITE ( 90 )  bc_par_b, bc_par_lr, bc_par_ns, bc_par_t,                    &
-                  last_particle_release_time, number_of_particle_groups,       &
-                  particle_groups, time_write_particle_data
-
-    WRITE ( 90 )  prt_count
+    INTEGER(iwp) ::  start_index                     !<
+    INTEGER(iwp) ::  start_index_on_pe               !<
+
+    INTEGER(iwp), DIMENSION(0:numprocs-1) ::  nr_particles_global
+    INTEGER(iwp), DIMENSION(0:numprocs-1) ::  nr_particles_local
+
+    INTEGER(idp), ALLOCATABLE, DIMENSION(:,:,:) ::  prt_global_index
+
+
+    IF ( TRIM( restart_data_format_output ) == 'fortran_binary' )  THEN
+!
+!--    First open the output unit.
+       IF ( myid_char == '' )  THEN
+          OPEN ( 90, FILE='PARTICLE_RESTART_DATA_OUT'//myid_char, &
+                     FORM='UNFORMATTED')
+       ELSE
+          IF ( myid == 0 )  CALL local_system( 'mkdir PARTICLE_RESTART_DATA_OUT' )
+#if defined( __parallel )
+!
+!--       Set a barrier in order to allow that thereafter all other processors
+!--       in the directory created by PE0 can open their file
+          CALL MPI_BARRIER( comm2d, ierr )
+#endif
+          OPEN ( 90, FILE='PARTICLE_RESTART_DATA_OUT/'//myid_char, &
+                     FORM='UNFORMATTED' )
+       ENDIF
+
+!
+!--    Write the version number of the binary format.
+!--    Attention: After changes to the following output commands the version
+!--    ---------  number of the variable particle_binary_version must be
+!--               changed! Also, the version number and the list of arrays
+!--               to be read in lpm_read_restart_file must be adjusted
+!--               accordingly.
+       particle_binary_version = '4.0'
+       WRITE ( 90 )  particle_binary_version
+
+!
+!--    Write some particle parameters, the size of the particle arrays
+       WRITE ( 90 )  bc_par_b, bc_par_lr, bc_par_ns, bc_par_t,                    &
+                     last_particle_release_time, number_of_particle_groups,       &
+                     particle_groups, time_write_particle_data
+
+       WRITE ( 90 )  prt_count
           
-    DO  ip = nxl, nxr
-       DO  jp = nys, nyn
-          DO  kp = nzb+1, nzt
-             number_of_particles = prt_count(kp,jp,ip)
-             particles => grid_particles(kp,jp,ip)%particles(1:number_of_particles)
-             IF ( number_of_particles <= 0 )  CYCLE
-             WRITE ( 90 )  particles
+       DO  ip = nxl, nxr
+          DO  jp = nys, nyn
+             DO  kp = nzb+1, nzt
+                number_of_particles = prt_count(kp,jp,ip)
+                particles => grid_particles(kp,jp,ip)%particles(1:number_of_particles)
+                IF ( number_of_particles <= 0 )  CYCLE
+                WRITE ( 90 )  particles
+             ENDDO
           ENDDO
        ENDDO
-    ENDDO
-
-    CLOSE ( 90 )
+
+       CLOSE ( 90 )
 
 #if defined( __parallel )
@@ -3314,5 +3428,4 @@
 #endif
 
-    IF ( TRIM( restart_data_format_output ) == 'fortran_binary' )  THEN
 
        IF ( ALLOCATED( seq_random_array_particles ) )  THEN
@@ -3321,5 +3434,7 @@
        ENDIF
 
+
     ELSEIF ( restart_data_format_output(1:3) == 'mpi' )  THEN
+
 
        IF ( ALLOCATED( seq_random_array_particles ) )  THEN
@@ -3330,4 +3445,51 @@
        ENDIF
 
+       ALLOCATE( prt_global_index(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
+
+#if defined( __parallel )
+!--    TODO: needs to be replaced by standard PALM message
+       IF ( TRIM( restart_data_format_output ) == 'mpi_shared_memory' )   THEN
+          WRITE( 9, * )  'mpi_shared_memory is NOT implemented yet for particle IO'
+          FLUSH( 9 )
+          CALL MPI_ABORT( MPI_COMM_WORLD, 1, ierr )
+       ENDIF
+#endif
+
+       CALL rd_mpi_io_particle_filetypes
+
+       nr_particles_local = 0
+       nr_particles_local(myid) = SUM( prt_count )
+
+#if defined( __parallel )
+       CALL MPI_ALLREDUCE( nr_particles_local, nr_particles_global, numprocs, MPI_INTEGER,         &
+                           MPI_SUM, comm2d, ierr )
+#else
+       nr_particles_global = nr_particles_local
+#endif
+
+       start_index_on_pe = 0
+       IF ( myid > 0 )  THEN
+          DO  i = 1, myid
+             start_index_on_pe = start_index_on_pe + nr_particles_global(i-1)
+          ENDDO
+       ENDIF
+
+       CALL wrd_mpi_io( 'prt_count', prt_count )
+
+       start_index = start_index_on_pe
+       DO  i = nxl, nxr
+          DO  j = nys, nyn
+             DO  k = nzb, nzt+1
+                prt_global_index(k,j,i) = start_index
+                start_index             = start_index + prt_count(k,j,i)
+             ENDDO
+          ENDDO
+       ENDDO
+
+       CALL wrd_mpi_io( 'prt_global_index', prt_global_index )
+       CALL wrd_mpi_io_particles( 'particles', prt_global_index )
+
+       DEALLOCATE( prt_global_index )
+
     ENDIF
 
@@ -3341,4 +3503,11 @@
 !------------------------------------------------------------------------------! 
  SUBROUTINE lpm_wrd_global
+
+#if defined( __parallel )
+    INTEGER :: ierr  !<
+#endif
+
+    REAL(wp), DIMENSION(4,max_number_of_particle_groups) ::  particle_groups_array  !<
+
  
     IF ( TRIM( restart_data_format_output ) == 'fortran_binary' )  THEN
@@ -3362,4 +3531,35 @@
        CALL wrd_mpi_io( 'interpolation_simple_predictor', interpolation_simple_predictor )
        CALL wrd_mpi_io( 'interpolation_trilinear', interpolation_trilinear )
+!
+!--    Write some global particle parameters
+!--    In case of Fortran binary format, these variables are written to unit 90
+       CALL wrd_mpi_io( 'bc_par_b', bc_par_b )
+       CALL wrd_mpi_io( 'bc_par_lr', bc_par_lr )
+       CALL wrd_mpi_io( 'bc_par_ns', bc_par_ns )
+       CALL wrd_mpi_io( 'bc_par_t', bc_par_t )
+       CALL wrd_mpi_io( 'last_particle_release_time', last_particle_release_time )
+       CALL wrd_mpi_io( 'number_of_particle_groups', number_of_particle_groups )
+       CALL wrd_mpi_io( 'time_write_particle_data', time_write_particle_data )
+
+!
+!--    Write particle_group informations via 2D array to avoid another overlay in
+!--    restart_data_mpi_io_mod.
+!--    TODO: convert the following to a standard PALM message
+       IF( STORAGE_SIZE( particle_groups(1) ) / (wp*8) /= 4 )  THEN
+          WRITE( 9, * )  'size of structure particle_groups_type has changed '
+          FLUSH( 9 )
+#if defined( __parallel )
+          CALL MPI_ABORT( MPI_COMM_WORLD, 1, ierr )
+#else
+          STOP 'error'
+#endif
+       ENDIF
+
+       particle_groups_array(1,:) = particle_groups(:)%density_ratio
+       particle_groups_array(2,:) = particle_groups(:)%radius
+       particle_groups_array(3,:) = particle_groups(:)%exp_arg
+       particle_groups_array(4,:) = particle_groups(:)%exp_term
+
+       CALL wrd_mpi_io_global_array( 'particle_groups', particle_groups_array )
 
     ENDIF
@@ -3412,8 +3612,46 @@
  SUBROUTINE lpm_rrd_global_mpi
 
+#if defined( __parallel )
+    INTEGER    :: ierr    !<
+#endif
+
+    REAL(wp), DIMENSION(4,max_number_of_particle_groups) ::  particle_groups_array  !<
+
+
     CALL rrd_mpi_io( 'curvature_solution_effects', curvature_solution_effects )
     CALL rrd_mpi_io( 'interpolation_simple_corrector', interpolation_simple_corrector )
     CALL rrd_mpi_io( 'interpolation_simple_predictor', interpolation_simple_predictor )
     CALL rrd_mpi_io( 'interpolation_trilinear', interpolation_trilinear )
+!
+!-- Read some particle parameters.
+!-- In case of Fortran binary format, these variables are read from unit 90.
+    CALL rrd_mpi_io( 'bc_par_b', bc_par_b )
+    CALL rrd_mpi_io( 'bc_par_lr', bc_par_lr )
+    CALL rrd_mpi_io( 'bc_par_ns', bc_par_ns )
+    CALL rrd_mpi_io( 'bc_par_t', bc_par_t )
+    CALL rrd_mpi_io( 'last_particle_release_time', last_particle_release_time )
+    CALL rrd_mpi_io( 'number_of_particle_groups', number_of_particle_groups )
+    CALL rrd_mpi_io( 'time_write_particle_data', time_write_particle_data )
+
+!
+!-- Read particle group information via 2d-array to avoid another overlay in
+!-- restart_data_mpi_io_mod.
+!-- TODO: convert the following to a standard PALM message
+    IF ( STORAGE_SIZE( particle_groups(1) ) / (wp*8) /= 4 )  THEN
+       WRITE( 9, * )  'size of structure particle_groups_type has changed '
+       FLUSH( 9 )
+#if defined( __parallel )
+       CALL MPI_ABORT( MPI_COMM_WORLD, 1, ierr )
+#else
+       STOP 'error'
+#endif
+    ENDIF
+
+    CALL rrd_mpi_io_global_array( 'particle_groups', particle_groups_array )
+
+    particle_groups(:)%density_ratio = particle_groups_array(1,:)
+    particle_groups(:)%radius        = particle_groups_array(2,:)
+    particle_groups(:)%exp_arg       = particle_groups_array(3,:)
+    particle_groups(:)%exp_term      = particle_groups_array(4,:)
 
  END SUBROUTINE lpm_rrd_global_mpi
