Index: src/FLEXPART_MPI.f90
===================================================================
--- src/FLEXPART_MPI.f90	(revision 79abee91596b840b8be5c7b61935df1d168db264)
+++ src/FLEXPART_MPI.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -55,13 +55,13 @@
 
 
-! Initialize mpi
-!*********************
+  ! Initialize mpi
+  !*********************
   call mpif_init
 
   if (mp_measure_time) call mpif_mtime('flexpart',0)
 
-! Initialize arrays in com_mod 
-!*****************************
-  call com_mod_allocate_part(maxpart_mpi)
+  ! Initialize arrays in com_mod 
+  !*****************************
+  if (.not.lmpreader) call com_mod_allocate_part(maxpart_mpi)
 
   ! Generate a large number of random numbers
@@ -306,7 +306,9 @@
   endif
 
-  do j=1, size(itra1) ! maxpart_mpi
-    itra1(j)=-999999999
-  end do
+  if (.not.lmpreader) then
+    do j=1, size(itra1) ! maxpart_mpi
+      itra1(j)=-999999999
+    end do
+  end if
 
   ! For continuation of previous run, read in particle positions
@@ -463,6 +465,8 @@
   if (lroot) then
     write(*,*) '**********************************************'
-    write(*,*) 'Total number of occurences of below-cloud scavenging', tot_blc_count
-    write(*,*) 'Total number of occurences of in-cloud    scavenging', tot_inc_count
+    write(*,*) 'Total number of occurences of below-cloud scavenging', &
+         & tot_blc_count
+    write(*,*) 'Total number of occurences of in-cloud    scavenging', &
+         & tot_inc_count
     write(*,*) '**********************************************'
 
Index: src/boundcond_domainfill_mpi.f90
===================================================================
--- src/boundcond_domainfill_mpi.f90	(revision 0f7835d03c332f5ff00577f23b0a0d791e42b9dc)
+++ src/boundcond_domainfill_mpi.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -21,26 +21,37 @@
 
 subroutine boundcond_domainfill(itime,loutend)
-  !                                  i      i
-  !*****************************************************************************
-  !                                                                            *
-  ! Particles are created by this subroutine continuously throughout the       *
-  ! simulation at the boundaries of the domain-filling box.                    *
-  ! All particles carry the same amount of mass which alltogether comprises the*
-  ! mass of air within the box, which remains (more or less) constant.         *
-  !                                                                            *
-  !     Author: A. Stohl                                                       *
-  !                                                                            *
-  !     16 October 2002                                                        *
-  !                                                                            *
-  !*****************************************************************************
-  !                                                                            *
-  ! Variables:                                                                 *
-  !                                                                            *
-  ! nx_we(2)       grid indices for western and eastern boundary of domain-    *
-  !                filling trajectory calculations                             *
-  ! ny_sn(2)       grid indices for southern and northern boundary of domain-  *
-  !                filling trajectory calculations                             *
-  !                                                                            *
-  !*****************************************************************************
+!                                  i      i
+!*****************************************************************************
+!                                                                            *
+! Particles are created by this subroutine continuously throughout the       *
+! simulation at the boundaries of the domain-filling box.                    *
+! All particles carry the same amount of mass which alltogether comprises the*
+! mass of air within the box, which remains (more or less) constant.         *
+!                                                                            *
+!     Author: A. Stohl                                                       *
+!                                                                            *
+!     16 October 2002                                                        *
+!                                                                            *
+!*****************************************************************************
+!                                                                            *
+! Variables:                                                                 *
+!                                                                            *
+! nx_we(2)       grid indices for western and eastern boundary of domain-    *
+!                filling trajectory calculations                             *
+! ny_sn(2)       grid indices for southern and northern boundary of domain-  *
+!                filling trajectory calculations                             *
+!                                                                            *
+!*****************************************************************************
+!  CHANGES                                                                   
+!    08/2016 eso: MPI version:                                                
+!
+!   -Root process release particles and distributes to other processes.
+!    Temporary arrays are used, also for the non-root (receiving) processes.
+!   -The scheme can be improved by having all processes report numpart
+!    (keeping track of how many particles have left the domain), so that
+!    a proportional amount of new particles can be distributed (however
+!    we have a separate function called from timemanager that will
+!    redistribute particles among processes if there are imbalances)     
+!*****************************************************************************
 
   use point_mod
@@ -55,5 +66,6 @@
   integer :: itime,in,indz,indzp,i,loutend
   integer :: j,k,ix,jy,m,indzh,indexh,minpart,ipart,mmass
-  integer :: numactiveparticles
+  integer :: numactiveparticles, numpart_total, rel_counter
+  integer,allocatable,dimension(:) ::  numrel_mpi !, numactiveparticles_mpi
 
   real :: windl(2),rhol(2)
@@ -66,7 +78,12 @@
 
   integer :: idummy = -11
+  integer :: mtag
   logical :: first_call=.true.
-
-  ! Use different seed for each process
+! Sizes of temporary arrays are maxpartfract*maxpart. Increase maxpartfract if 
+! needed.  
+  real,parameter :: maxpartfract=0.1
+  integer :: tmp_size = int(maxpartfract*maxpart)
+
+! Use different seed for each process
   if (first_call) then
     idummy=idummy+mp_seed
@@ -75,6 +92,6 @@
 
 
-  ! If domain-filling is global, no boundary conditions are needed
-  !***************************************************************
+! If domain-filling is global, no boundary conditions are needed
+!***************************************************************
 
   if (gdomainfill) return
@@ -82,8 +99,14 @@
   accmasst=0.
   numactiveparticles=0
-
-  ! Terminate trajectories that have left the domain, if domain-filling
-  ! trajectory calculation domain is not global
-  !********************************************************************
+! Keep track of active particles on each process
+  allocate(numrel_mpi(0:mp_partgroup_np-1))
+! numactiveparticles_mpi(0:mp_partgroup_np-1)
+
+! New particles to be released on each process
+  numrel_mpi(:)=0
+
+! Terminate trajectories that have left the domain, if domain-filling
+! trajectory calculation domain is not global. Done for all processes
+!********************************************************************
 
   do i=1,numpart
@@ -98,496 +121,666 @@
          numactiveparticles+1
   end do
-
-
-  ! Determine auxiliary variables for time interpolation
-  !*****************************************************
-
-  dt1=real(itime-memtime(1))
-  dt2=real(memtime(2)-itime)
-  dtt=1./(dt1+dt2)
-
-  ! Initialize auxiliary variable used to search for vacant storage space
-  !**********************************************************************
-
-  minpart=1
-
-  !***************************************
-  ! Western and eastern boundary condition
-  !***************************************
-
-  ! Loop from south to north
-  !*************************
-
-  do jy=ny_sn(1),ny_sn(2)
-
-  ! Loop over western (index 1) and eastern (index 2) boundary
-  !***********************************************************
-
-    do k=1,2
-
-  ! Loop over all release locations in a column
-  !********************************************
-
-      do j=1,numcolumn_we(k,jy)
-
-  ! Determine, for each release location, the area of the corresponding boundary
-  !*****************************************************************************
-
-        if (j.eq.1) then
-          deltaz=(zcolumn_we(k,jy,2)+zcolumn_we(k,jy,1))/2.
-        else if (j.eq.numcolumn_we(k,jy)) then
-  !        deltaz=height(nz)-(zcolumn_we(k,jy,j-1)+
-  !    +        zcolumn_we(k,jy,j))/2.
-  ! In order to avoid taking a very high column for very many particles,
-  ! use the deltaz from one particle below instead
-          deltaz=(zcolumn_we(k,jy,j)-zcolumn_we(k,jy,j-2))/2.
-        else
-          deltaz=(zcolumn_we(k,jy,j+1)-zcolumn_we(k,jy,j-1))/2.
-        endif
-        if ((jy.eq.ny_sn(1)).or.(jy.eq.ny_sn(2))) then
-          boundarea=deltaz*111198.5/2.*dy
-        else
-          boundarea=deltaz*111198.5*dy
-        endif
-
-
-  ! Interpolate the wind velocity and density to the release location
-  !******************************************************************
-
-  ! Determine the model level below the release position
-  !*****************************************************
-
-        do i=2,nz
-          if (height(i).gt.zcolumn_we(k,jy,j)) then
-            indz=i-1
-            indzp=i
-            goto 6
+!  numactiveparticles_mpi(mp_partid) = numactiveparticles
+
+
+! Collect number of active particles from all processes
+  ! call MPI_Allgather(numactiveparticles, 1, MPI_INTEGER, &
+  !      &numactiveparticles_mpi, 1, MPI_INTEGER, mp_comm_used, mp_ierr)
+
+
+! Total number of new releases
+  numpart_total = 0
+
+
+! This section only done by root process
+!***************************************
+
+  if (lroot) then
+
+! Use separate arrays for newly released particles
+!*************************************************
+
+    allocate(itra1_tmp(tmp_size),npoint_tmp(tmp_size),nclass_tmp(tmp_size),&
+         & idt_tmp(tmp_size),itramem_tmp(tmp_size),itrasplit_tmp(tmp_size),&
+         & xtra1_tmp(tmp_size),ytra1_tmp(tmp_size),ztra1_tmp(tmp_size),&
+         & xmass1_tmp(tmp_size, maxspec))
+
+! Initialize all particles as non-existent    
+    itra1_tmp(:)=-999999999
+
+! Determine auxiliary variables for time interpolation
+!*****************************************************
+
+    dt1=real(itime-memtime(1))
+    dt2=real(memtime(2)-itime)
+    dtt=1./(dt1+dt2)
+
+! Initialize auxiliary variable used to search for vacant storage space
+!**********************************************************************
+
+    minpart=1
+
+!***************************************
+! Western and eastern boundary condition
+!***************************************
+
+! Loop from south to north
+!*************************
+
+    do jy=ny_sn(1),ny_sn(2)
+
+! Loop over western (index 1) and eastern (index 2) boundary
+!***********************************************************
+
+      do k=1,2
+
+! Loop over all release locations in a column
+!********************************************
+
+        do j=1,numcolumn_we(k,jy)
+
+! Determine, for each release location, the area of the corresponding boundary
+!*****************************************************************************
+
+          if (j.eq.1) then
+            deltaz=(zcolumn_we(k,jy,2)+zcolumn_we(k,jy,1))/2.
+          else if (j.eq.numcolumn_we(k,jy)) then
+!        deltaz=height(nz)-(zcolumn_we(k,jy,j-1)+
+!    +        zcolumn_we(k,jy,j))/2.
+! In order to avoid taking a very high column for very many particles,
+! use the deltaz from one particle below instead
+            deltaz=(zcolumn_we(k,jy,j)-zcolumn_we(k,jy,j-2))/2.
+          else
+            deltaz=(zcolumn_we(k,jy,j+1)-zcolumn_we(k,jy,j-1))/2.
           endif
-        end do
-6       continue
-
-  ! Vertical distance to the level below and above current position
-  !****************************************************************
-
-        dz1=zcolumn_we(k,jy,j)-height(indz)
-        dz2=height(indzp)-zcolumn_we(k,jy,j)
-        dz=1./(dz1+dz2)
-
-  ! Vertical and temporal interpolation
-  !************************************
-
-        do m=1,2
-          indexh=memind(m)
-          do in=1,2
-            indzh=indz+in-1
-            windl(in)=uu(nx_we(k),jy,indzh,indexh)
-            rhol(in)=rho(nx_we(k),jy,indzh,indexh)
-          end do
-
-          windhl(m)=(dz2*windl(1)+dz1*windl(2))*dz
-          rhohl(m)=(dz2*rhol(1)+dz1*rhol(2))*dz
-        end do
-
-        windx=(windhl(1)*dt2+windhl(2)*dt1)*dtt
-        rhox=(rhohl(1)*dt2+rhohl(2)*dt1)*dtt
-
-  ! Calculate mass flux, divided by number of processes
-  !****************************************************
-
-        fluxofmass=windx*rhox*boundarea*real(lsynctime)/mp_partgroup_np
-
-
-  ! If the mass flux is directed into the domain, add it to previous mass fluxes;
-  ! if it is out of the domain, set accumulated mass flux to zero
-  !******************************************************************************
-
-        if (k.eq.1) then
-          if (fluxofmass.ge.0.) then
-            acc_mass_we(k,jy,j)=acc_mass_we(k,jy,j)+fluxofmass
+          if ((jy.eq.ny_sn(1)).or.(jy.eq.ny_sn(2))) then
+            boundarea=deltaz*111198.5/2.*dy
           else
-            acc_mass_we(k,jy,j)=0.
+            boundarea=deltaz*111198.5*dy
           endif
-        else
-          if (fluxofmass.le.0.) then
-            acc_mass_we(k,jy,j)=acc_mass_we(k,jy,j)+abs(fluxofmass)
-          else
-            acc_mass_we(k,jy,j)=0.
-          endif
-        endif
-        accmasst=accmasst+acc_mass_we(k,jy,j)
-
-  ! If the accumulated mass exceeds half the mass that each particle shall carry,
-  ! one (or more) particle(s) is (are) released and the accumulated mass is
-  ! reduced by the mass of this (these) particle(s)
-  !******************************************************************************
-
-        if (acc_mass_we(k,jy,j).ge.xmassperparticle/2.) then
-          mmass=int((acc_mass_we(k,jy,j)+xmassperparticle/2.)/ &
-               xmassperparticle)
-          acc_mass_we(k,jy,j)=acc_mass_we(k,jy,j)- &
-               real(mmass)*xmassperparticle
-        else
-          mmass=0
-        endif
-
-        do m=1,mmass
-          do ipart=minpart,maxpart_mpi
-
-  ! If a vacant storage space is found, attribute everything to this array element
-  !*****************************************************************************
-
-            if (itra1(ipart).ne.itime) then
-
-  ! Assign particle positions
-  !**************************
-
-              xtra1(ipart)=real(nx_we(k))
-              if (jy.eq.ny_sn(1)) then
-                ytra1(ipart)=real(jy)+0.5*ran1(idummy)
-              else if (jy.eq.ny_sn(2)) then
-                ytra1(ipart)=real(jy)-0.5*ran1(idummy)
-              else
-                ytra1(ipart)=real(jy)+(ran1(idummy)-.5)
-              endif
-              if (j.eq.1) then
-                ztra1(ipart)=zcolumn_we(k,jy,1)+(zcolumn_we(k,jy,2)- &
-                     zcolumn_we(k,jy,1))/4.
-              else if (j.eq.numcolumn_we(k,jy)) then
-                ztra1(ipart)=(2.*zcolumn_we(k,jy,j)+ &
-                     zcolumn_we(k,jy,j-1)+height(nz))/4.
-              else
-                ztra1(ipart)=zcolumn_we(k,jy,j-1)+ran1(idummy)* &
-                     (zcolumn_we(k,jy,j+1)-zcolumn_we(k,jy,j-1))
-              endif
-
-  ! Interpolate PV to the particle position
-  !****************************************
-              ixm=int(xtra1(ipart))
-              jym=int(ytra1(ipart))
-              ixp=ixm+1
-              jyp=jym+1
-              ddx=xtra1(ipart)-real(ixm)
-              ddy=ytra1(ipart)-real(jym)
-              rddx=1.-ddx
-              rddy=1.-ddy
-              p1=rddx*rddy
-              p2=ddx*rddy
-              p3=rddx*ddy
-              p4=ddx*ddy
-              do i=2,nz
-                if (height(i).gt.ztra1(ipart)) then
-                  indzm=i-1
-                  indzp=i
-                  goto 26
-                endif
-              end do
-26            continue
-              dz1=ztra1(ipart)-height(indzm)
-              dz2=height(indzp)-ztra1(ipart)
-              dz=1./(dz1+dz2)
-              do mm=1,2
-                indexh=memind(mm)
-                do in=1,2
-                  indzh=indzm+in-1
-                  y1(in)=p1*pv(ixm,jym,indzh,indexh) &
-                       +p2*pv(ixp,jym,indzh,indexh) &
-                       +p3*pv(ixm,jyp,indzh,indexh) &
-                       +p4*pv(ixp,jyp,indzh,indexh)
-                end do
-                yh1(mm)=(dz2*y1(1)+dz1*y1(2))*dz
-              end do
-              pvpart=(yh1(1)*dt2+yh1(2)*dt1)*dtt
-              ylat=ylat0+ytra1(ipart)*dy
-              if (ylat.lt.0.) pvpart=-1.*pvpart
-
-
-  ! For domain-filling option 2 (stratospheric O3), do the rest only in the stratosphere
-  !*****************************************************************************
-
-              if (((ztra1(ipart).gt.3000.).and. &
-                   (pvpart.gt.pvcrit)).or.(mdomainfill.eq.1)) then
-                nclass(ipart)=min(int(ran1(idummy)* &
-                     real(nclassunc))+1,nclassunc)
-                numactiveparticles=numactiveparticles+1
-                numparticlecount=numparticlecount+1
-                npoint(ipart)=numparticlecount
-                idt(ipart)=mintime
-                itra1(ipart)=itime
-                itramem(ipart)=itra1(ipart)
-                itrasplit(ipart)=itra1(ipart)+ldirect*itsplit
-                xmass1(ipart,1)=xmassperparticle
-                if (mdomainfill.eq.2) xmass1(ipart,1)= &
-                     xmass1(ipart,1)*pvpart*48./29.*ozonescale/10.**9
-              else
-                goto 71
-              endif
-
-
-  ! Increase numpart, if necessary
-  !*******************************
-
-              numpart=max(numpart,ipart)
-              goto 73      ! Storage space has been found, stop searching
+
+
+! Interpolate the wind velocity and density to the release location
+!******************************************************************
+
+! Determine the model level below the release position
+!*****************************************************
+
+          do i=2,nz
+            if (height(i).gt.zcolumn_we(k,jy,j)) then
+              indz=i-1
+              indzp=i
+              goto 6
             endif
           end do
-          if (ipart.gt.maxpart_mpi) &
-               stop 'boundcond_domainfill.f: too many particles required'
-73        minpart=ipart+1
-71        continue
+6         continue
+
+! Vertical distance to the level below and above current position
+!****************************************************************
+
+          dz1=zcolumn_we(k,jy,j)-height(indz)
+          dz2=height(indzp)-zcolumn_we(k,jy,j)
+          dz=1./(dz1+dz2)
+
+! Vertical and temporal interpolation
+!************************************
+
+          do m=1,2
+            indexh=memind(m)
+            do in=1,2
+              indzh=indz+in-1
+              windl(in)=uu(nx_we(k),jy,indzh,indexh)
+              rhol(in)=rho(nx_we(k),jy,indzh,indexh)
+            end do
+
+            windhl(m)=(dz2*windl(1)+dz1*windl(2))*dz
+            rhohl(m)=(dz2*rhol(1)+dz1*rhol(2))*dz
+          end do
+
+          windx=(windhl(1)*dt2+windhl(2)*dt1)*dtt
+          rhox=(rhohl(1)*dt2+rhohl(2)*dt1)*dtt
+
+! Calculate mass flux
+!********************
+
+          fluxofmass=windx*rhox*boundarea*real(lsynctime)
+
+
+! If the mass flux is directed into the domain, add it to previous mass fluxes;
+! if it is out of the domain, set accumulated mass flux to zero
+!******************************************************************************
+
+          if (k.eq.1) then
+            if (fluxofmass.ge.0.) then
+              acc_mass_we(k,jy,j)=acc_mass_we(k,jy,j)+fluxofmass
+            else
+              acc_mass_we(k,jy,j)=0.
+            endif
+          else
+            if (fluxofmass.le.0.) then
+              acc_mass_we(k,jy,j)=acc_mass_we(k,jy,j)+abs(fluxofmass)
+            else
+              acc_mass_we(k,jy,j)=0.
+            endif
+          endif
+          accmasst=accmasst+acc_mass_we(k,jy,j)
+
+! If the accumulated mass exceeds half the mass that each particle shall carry,
+! one (or more) particle(s) is (are) released and the accumulated mass is
+! reduced by the mass of this (these) particle(s)
+!******************************************************************************
+
+          if (acc_mass_we(k,jy,j).ge.xmassperparticle/2.) then
+            mmass=int((acc_mass_we(k,jy,j)+xmassperparticle/2.)/ &
+                 xmassperparticle)
+            acc_mass_we(k,jy,j)=acc_mass_we(k,jy,j)- &
+                 real(mmass)*xmassperparticle
+          else
+            mmass=0
+          endif
+
+          do m=1,mmass
+            do ipart=minpart,maxpart
+
+! If a vacant storage space is found, attribute everything to this array element
+! TODO: for the MPI version this test can be removed, as all 
+!       elements in _tmp arrays are initialized to zero
+!*****************************************************************************
+
+              if (itra1_tmp(ipart).ne.itime) then
+
+! Assign particle positions
+!**************************
+
+                xtra1_tmp(ipart)=real(nx_we(k))
+                if (jy.eq.ny_sn(1)) then
+                  ytra1_tmp(ipart)=real(jy)+0.5*ran1(idummy)
+                else if (jy.eq.ny_sn(2)) then
+                  ytra1_tmp(ipart)=real(jy)-0.5*ran1(idummy)
+                else
+                  ytra1_tmp(ipart)=real(jy)+(ran1(idummy)-.5)
+                endif
+                if (j.eq.1) then
+                  ztra1_tmp(ipart)=zcolumn_we(k,jy,1)+(zcolumn_we(k,jy,2)- &
+                       zcolumn_we(k,jy,1))/4.
+                else if (j.eq.numcolumn_we(k,jy)) then
+                  ztra1_tmp(ipart)=(2.*zcolumn_we(k,jy,j)+ &
+                       zcolumn_we(k,jy,j-1)+height(nz))/4.
+                else
+                  ztra1_tmp(ipart)=zcolumn_we(k,jy,j-1)+ran1(idummy)* &
+                       (zcolumn_we(k,jy,j+1)-zcolumn_we(k,jy,j-1))
+                endif
+
+! Interpolate PV to the particle position
+!****************************************
+                ixm=int(xtra1_tmp(ipart))
+                jym=int(ytra1_tmp(ipart))
+                ixp=ixm+1
+                jyp=jym+1
+                ddx=xtra1_tmp(ipart)-real(ixm)
+                ddy=ytra1_tmp(ipart)-real(jym)
+                rddx=1.-ddx
+                rddy=1.-ddy
+                p1=rddx*rddy
+                p2=ddx*rddy
+                p3=rddx*ddy
+                p4=ddx*ddy
+                do i=2,nz
+                  if (height(i).gt.ztra1_tmp(ipart)) then
+                    indzm=i-1
+                    indzp=i
+                    goto 26
+                  endif
+                end do
+26              continue
+                dz1=ztra1_tmp(ipart)-height(indzm)
+                dz2=height(indzp)-ztra1_tmp(ipart)
+                dz=1./(dz1+dz2)
+                do mm=1,2
+                  indexh=memind(mm)
+                  do in=1,2
+                    indzh=indzm+in-1
+                    y1(in)=p1*pv(ixm,jym,indzh,indexh) &
+                         +p2*pv(ixp,jym,indzh,indexh) &
+                         +p3*pv(ixm,jyp,indzh,indexh) &
+                         +p4*pv(ixp,jyp,indzh,indexh)
+                  end do
+                  yh1(mm)=(dz2*y1(1)+dz1*y1(2))*dz
+                end do
+                pvpart=(yh1(1)*dt2+yh1(2)*dt1)*dtt
+                ylat=ylat0+ytra1_tmp(ipart)*dy
+                if (ylat.lt.0.) pvpart=-1.*pvpart
+
+
+! For domain-filling option 2 (stratospheric O3), do the rest only in the stratosphere
+!*****************************************************************************
+
+                if (((ztra1_tmp(ipart).gt.3000.).and. &
+                     (pvpart.gt.pvcrit)).or.(mdomainfill.eq.1)) then
+                  nclass_tmp(ipart)=min(int(ran1(idummy)* &
+                       real(nclassunc))+1,nclassunc)
+                  numactiveparticles=numactiveparticles+1
+                  numparticlecount=numparticlecount+1
+                  npoint_tmp(ipart)=numparticlecount
+                  idt_tmp(ipart)=mintime
+                  itra1_tmp(ipart)=itime
+                  itramem_tmp(ipart)=itra1_tmp(ipart)
+                  itrasplit_tmp(ipart)=itra1_tmp(ipart)+ldirect*itsplit
+                  xmass1_tmp(ipart,1)=xmassperparticle
+                  if (mdomainfill.eq.2) xmass1_tmp(ipart,1)= &
+                       xmass1_tmp(ipart,1)*pvpart*48./29.*ozonescale/10.**9
+                else
+                  goto 71
+                endif
+
+
+! Increase numpart, if necessary
+!*******************************
+
+                numpart_total=max(numpart_total,ipart)
+                goto 73      ! Storage space has been found, stop searching
+              endif
+            end do
+            if (ipart.gt.tmp_size) &
+                 stop 'boundcond_domainfill_mpi.f90: too many particles required'
+73          minpart=ipart+1
+71          continue
+          end do
+
+
         end do
-
-
       end do
     end do
-  end do
-
-
-  !*****************************************
-  ! Southern and northern boundary condition
-  !*****************************************
-
-  ! Loop from west to east
-  !***********************
-
-  do ix=nx_we(1),nx_we(2)
-
-  ! Loop over southern (index 1) and northern (index 2) boundary
-  !*************************************************************
-
-    do k=1,2
-      ylat=ylat0+real(ny_sn(k))*dy
-      cosfact=cos(ylat*pi180)
-
-  ! Loop over all release locations in a column
-  !********************************************
-
-      do j=1,numcolumn_sn(k,ix)
-
-  ! Determine, for each release location, the area of the corresponding boundary
-  !*****************************************************************************
-
-        if (j.eq.1) then
-          deltaz=(zcolumn_sn(k,ix,2)+zcolumn_sn(k,ix,1))/2.
-        else if (j.eq.numcolumn_sn(k,ix)) then
-  !        deltaz=height(nz)-(zcolumn_sn(k,ix,j-1)+
-  !    +        zcolumn_sn(k,ix,j))/2.
-  ! In order to avoid taking a very high column for very many particles,
-  ! use the deltaz from one particle below instead
-          deltaz=(zcolumn_sn(k,ix,j)-zcolumn_sn(k,ix,j-2))/2.
-        else
-          deltaz=(zcolumn_sn(k,ix,j+1)-zcolumn_sn(k,ix,j-1))/2.
-        endif
-        if ((ix.eq.nx_we(1)).or.(ix.eq.nx_we(2))) then
-          boundarea=deltaz*111198.5/2.*cosfact*dx
-        else
-          boundarea=deltaz*111198.5*cosfact*dx
-        endif
-
-
-  ! Interpolate the wind velocity and density to the release location
-  !******************************************************************
-
-  ! Determine the model level below the release position
-  !*****************************************************
-
-        do i=2,nz
-          if (height(i).gt.zcolumn_sn(k,ix,j)) then
-            indz=i-1
-            indzp=i
-            goto 16
+
+
+!*****************************************
+! Southern and northern boundary condition
+!*****************************************
+
+! Loop from west to east
+!***********************
+
+    do ix=nx_we(1),nx_we(2)
+
+! Loop over southern (index 1) and northern (index 2) boundary
+!*************************************************************
+
+      do k=1,2
+        ylat=ylat0+real(ny_sn(k))*dy
+        cosfact=cos(ylat*pi180)
+
+! Loop over all release locations in a column
+!********************************************
+
+        do j=1,numcolumn_sn(k,ix)
+
+! Determine, for each release location, the area of the corresponding boundary
+!*****************************************************************************
+
+          if (j.eq.1) then
+            deltaz=(zcolumn_sn(k,ix,2)+zcolumn_sn(k,ix,1))/2.
+          else if (j.eq.numcolumn_sn(k,ix)) then
+!        deltaz=height(nz)-(zcolumn_sn(k,ix,j-1)+
+!    +        zcolumn_sn(k,ix,j))/2.
+! In order to avoid taking a very high column for very many particles,
+! use the deltaz from one particle below instead
+            deltaz=(zcolumn_sn(k,ix,j)-zcolumn_sn(k,ix,j-2))/2.
+          else
+            deltaz=(zcolumn_sn(k,ix,j+1)-zcolumn_sn(k,ix,j-1))/2.
           endif
-        end do
-16      continue
-
-  ! Vertical distance to the level below and above current position
-  !****************************************************************
-
-        dz1=zcolumn_sn(k,ix,j)-height(indz)
-        dz2=height(indzp)-zcolumn_sn(k,ix,j)
-        dz=1./(dz1+dz2)
-
-  ! Vertical and temporal interpolation
-  !************************************
-
-        do m=1,2
-          indexh=memind(m)
-          do in=1,2
-            indzh=indz+in-1
-            windl(in)=vv(ix,ny_sn(k),indzh,indexh)
-            rhol(in)=rho(ix,ny_sn(k),indzh,indexh)
-          end do
-
-          windhl(m)=(dz2*windl(1)+dz1*windl(2))*dz
-          rhohl(m)=(dz2*rhol(1)+dz1*rhol(2))*dz
-        end do
-
-        windx=(windhl(1)*dt2+windhl(2)*dt1)*dtt
-        rhox=(rhohl(1)*dt2+rhohl(2)*dt1)*dtt
-
-  ! Calculate mass flux, divided by number of processes
-  !****************************************************
-
-        fluxofmass=windx*rhox*boundarea*real(lsynctime)/mp_partgroup_np
-
-  ! If the mass flux is directed into the domain, add it to previous mass fluxes;
-  ! if it is out of the domain, set accumulated mass flux to zero
-  !******************************************************************************
-
-        if (k.eq.1) then
-          if (fluxofmass.ge.0.) then
-            acc_mass_sn(k,ix,j)=acc_mass_sn(k,ix,j)+fluxofmass
+          if ((ix.eq.nx_we(1)).or.(ix.eq.nx_we(2))) then
+            boundarea=deltaz*111198.5/2.*cosfact*dx
           else
-            acc_mass_sn(k,ix,j)=0.
+            boundarea=deltaz*111198.5*cosfact*dx
           endif
-        else
-          if (fluxofmass.le.0.) then
-            acc_mass_sn(k,ix,j)=acc_mass_sn(k,ix,j)+abs(fluxofmass)
-          else
-            acc_mass_sn(k,ix,j)=0.
-          endif
-        endif
-        accmasst=accmasst+acc_mass_sn(k,ix,j)
-
-  ! If the accumulated mass exceeds half the mass that each particle shall carry,
-  ! one (or more) particle(s) is (are) released and the accumulated mass is
-  ! reduced by the mass of this (these) particle(s)
-  !******************************************************************************
-
-        if (acc_mass_sn(k,ix,j).ge.xmassperparticle/2.) then
-          mmass=int((acc_mass_sn(k,ix,j)+xmassperparticle/2.)/ &
-               xmassperparticle)
-          acc_mass_sn(k,ix,j)=acc_mass_sn(k,ix,j)- &
-               real(mmass)*xmassperparticle
-        else
-          mmass=0
-        endif
-
-        do m=1,mmass
-          do ipart=minpart,maxpart_mpi
-
-  ! If a vacant storage space is found, attribute everything to this array element
-  !*****************************************************************************
-
-            if (itra1(ipart).ne.itime) then
-
-  ! Assign particle positions
-  !**************************
-
-              ytra1(ipart)=real(ny_sn(k))
-              if (ix.eq.nx_we(1)) then
-                xtra1(ipart)=real(ix)+0.5*ran1(idummy)
-              else if (ix.eq.nx_we(2)) then
-                xtra1(ipart)=real(ix)-0.5*ran1(idummy)
-              else
-                xtra1(ipart)=real(ix)+(ran1(idummy)-.5)
-              endif
-              if (j.eq.1) then
-                ztra1(ipart)=zcolumn_sn(k,ix,1)+(zcolumn_sn(k,ix,2)- &
-                     zcolumn_sn(k,ix,1))/4.
-              else if (j.eq.numcolumn_sn(k,ix)) then
-                ztra1(ipart)=(2.*zcolumn_sn(k,ix,j)+ &
-                     zcolumn_sn(k,ix,j-1)+height(nz))/4.
-              else
-                ztra1(ipart)=zcolumn_sn(k,ix,j-1)+ran1(idummy)* &
-                     (zcolumn_sn(k,ix,j+1)-zcolumn_sn(k,ix,j-1))
-              endif
-
-
-  ! Interpolate PV to the particle position
-  !****************************************
-              ixm=int(xtra1(ipart))
-              jym=int(ytra1(ipart))
-              ixp=ixm+1
-              jyp=jym+1
-              ddx=xtra1(ipart)-real(ixm)
-              ddy=ytra1(ipart)-real(jym)
-              rddx=1.-ddx
-              rddy=1.-ddy
-              p1=rddx*rddy
-              p2=ddx*rddy
-              p3=rddx*ddy
-              p4=ddx*ddy
-              do i=2,nz
-                if (height(i).gt.ztra1(ipart)) then
-                  indzm=i-1
-                  indzp=i
-                  goto 126
-                endif
-              end do
-126           continue
-              dz1=ztra1(ipart)-height(indzm)
-              dz2=height(indzp)-ztra1(ipart)
-              dz=1./(dz1+dz2)
-              do mm=1,2
-                indexh=memind(mm)
-                do in=1,2
-                  indzh=indzm+in-1
-                  y1(in)=p1*pv(ixm,jym,indzh,indexh) &
-                       +p2*pv(ixp,jym,indzh,indexh) &
-                       +p3*pv(ixm,jyp,indzh,indexh) &
-                       +p4*pv(ixp,jyp,indzh,indexh)
-                end do
-                yh1(mm)=(dz2*y1(1)+dz1*y1(2))*dz
-              end do
-              pvpart=(yh1(1)*dt2+yh1(2)*dt1)*dtt
-              if (ylat.lt.0.) pvpart=-1.*pvpart
-
-
-  ! For domain-filling option 2 (stratospheric O3), do the rest only in the stratosphere
-  !*****************************************************************************
-
-              if (((ztra1(ipart).gt.3000.).and. &
-                   (pvpart.gt.pvcrit)).or.(mdomainfill.eq.1)) then
-                nclass(ipart)=min(int(ran1(idummy)* &
-                     real(nclassunc))+1,nclassunc)
-                numactiveparticles=numactiveparticles+1
-                numparticlecount=numparticlecount+1
-                npoint(ipart)=numparticlecount
-                idt(ipart)=mintime
-                itra1(ipart)=itime
-                itramem(ipart)=itra1(ipart)
-                itrasplit(ipart)=itra1(ipart)+ldirect*itsplit
-                xmass1(ipart,1)=xmassperparticle
-                if (mdomainfill.eq.2) xmass1(ipart,1)= &
-                     xmass1(ipart,1)*pvpart*48./29.*ozonescale/10.**9
-              else
-                goto 171
-              endif
-
-
-  ! Increase numpart, if necessary
-  !*******************************
-              numpart=max(numpart,ipart)
-              goto 173      ! Storage space has been found, stop searching
+
+
+! Interpolate the wind velocity and density to the release location
+!******************************************************************
+
+! Determine the model level below the release position
+!*****************************************************
+
+          do i=2,nz
+            if (height(i).gt.zcolumn_sn(k,ix,j)) then
+              indz=i-1
+              indzp=i
+              goto 16
             endif
           end do
-          if (ipart.gt.maxpart_mpi) &
-               stop 'boundcond_domainfill.f: too many particles required'
-173       minpart=ipart+1
-171       continue
+16        continue
+
+! Vertical distance to the level below and above current position
+!****************************************************************
+
+          dz1=zcolumn_sn(k,ix,j)-height(indz)
+          dz2=height(indzp)-zcolumn_sn(k,ix,j)
+          dz=1./(dz1+dz2)
+
+! Vertical and temporal interpolation
+!************************************
+
+          do m=1,2
+            indexh=memind(m)
+            do in=1,2
+              indzh=indz+in-1
+              windl(in)=vv(ix,ny_sn(k),indzh,indexh)
+              rhol(in)=rho(ix,ny_sn(k),indzh,indexh)
+            end do
+
+            windhl(m)=(dz2*windl(1)+dz1*windl(2))*dz
+            rhohl(m)=(dz2*rhol(1)+dz1*rhol(2))*dz
+          end do
+
+          windx=(windhl(1)*dt2+windhl(2)*dt1)*dtt
+          rhox=(rhohl(1)*dt2+rhohl(2)*dt1)*dtt
+
+! Calculate mass flux
+!********************
+
+          fluxofmass=windx*rhox*boundarea*real(lsynctime)
+
+! If the mass flux is directed into the domain, add it to previous mass fluxes;
+! if it is out of the domain, set accumulated mass flux to zero
+!******************************************************************************
+
+          if (k.eq.1) then
+            if (fluxofmass.ge.0.) then
+              acc_mass_sn(k,ix,j)=acc_mass_sn(k,ix,j)+fluxofmass
+            else
+              acc_mass_sn(k,ix,j)=0.
+            endif
+          else
+            if (fluxofmass.le.0.) then
+              acc_mass_sn(k,ix,j)=acc_mass_sn(k,ix,j)+abs(fluxofmass)
+            else
+              acc_mass_sn(k,ix,j)=0.
+            endif
+          endif
+          accmasst=accmasst+acc_mass_sn(k,ix,j)
+
+! If the accumulated mass exceeds half the mass that each particle shall carry,
+! one (or more) particle(s) is (are) released and the accumulated mass is
+! reduced by the mass of this (these) particle(s)
+!******************************************************************************
+
+          if (acc_mass_sn(k,ix,j).ge.xmassperparticle/2.) then
+            mmass=int((acc_mass_sn(k,ix,j)+xmassperparticle/2.)/ &
+                 xmassperparticle)
+            acc_mass_sn(k,ix,j)=acc_mass_sn(k,ix,j)- &
+                 real(mmass)*xmassperparticle
+          else
+            mmass=0
+          endif
+
+          do m=1,mmass
+            do ipart=minpart,maxpart
+
+! If a vacant storage space is found, attribute everything to this array element
+!*****************************************************************************
+
+              if (itra1_tmp(ipart).ne.itime) then
+
+! Assign particle positions
+!**************************
+
+                ytra1_tmp(ipart)=real(ny_sn(k))
+                if (ix.eq.nx_we(1)) then
+                  xtra1_tmp(ipart)=real(ix)+0.5*ran1(idummy)
+                else if (ix.eq.nx_we(2)) then
+                  xtra1_tmp(ipart)=real(ix)-0.5*ran1(idummy)
+                else
+                  xtra1_tmp(ipart)=real(ix)+(ran1(idummy)-.5)
+                endif
+                if (j.eq.1) then
+                  ztra1_tmp(ipart)=zcolumn_sn(k,ix,1)+(zcolumn_sn(k,ix,2)- &
+                       zcolumn_sn(k,ix,1))/4.
+                else if (j.eq.numcolumn_sn(k,ix)) then
+                  ztra1_tmp(ipart)=(2.*zcolumn_sn(k,ix,j)+ &
+                       zcolumn_sn(k,ix,j-1)+height(nz))/4.
+                else
+                  ztra1_tmp(ipart)=zcolumn_sn(k,ix,j-1)+ran1(idummy)* &
+                       (zcolumn_sn(k,ix,j+1)-zcolumn_sn(k,ix,j-1))
+                endif
+
+
+! Interpolate PV to the particle position
+!****************************************
+                ixm=int(xtra1_tmp(ipart))
+                jym=int(ytra1_tmp(ipart))
+                ixp=ixm+1
+                jyp=jym+1
+                ddx=xtra1_tmp(ipart)-real(ixm)
+                ddy=ytra1_tmp(ipart)-real(jym)
+                rddx=1.-ddx
+                rddy=1.-ddy
+                p1=rddx*rddy
+                p2=ddx*rddy
+                p3=rddx*ddy
+                p4=ddx*ddy
+                do i=2,nz
+                  if (height(i).gt.ztra1_tmp(ipart)) then
+                    indzm=i-1
+                    indzp=i
+                    goto 126
+                  endif
+                end do
+126             continue
+                dz1=ztra1_tmp(ipart)-height(indzm)
+                dz2=height(indzp)-ztra1_tmp(ipart)
+                dz=1./(dz1+dz2)
+                do mm=1,2
+                  indexh=memind(mm)
+                  do in=1,2
+                    indzh=indzm+in-1
+                    y1(in)=p1*pv(ixm,jym,indzh,indexh) &
+                         +p2*pv(ixp,jym,indzh,indexh) &
+                         +p3*pv(ixm,jyp,indzh,indexh) &
+                         +p4*pv(ixp,jyp,indzh,indexh)
+                  end do
+                  yh1(mm)=(dz2*y1(1)+dz1*y1(2))*dz
+                end do
+                pvpart=(yh1(1)*dt2+yh1(2)*dt1)*dtt
+                if (ylat.lt.0.) pvpart=-1.*pvpart
+
+
+! For domain-filling option 2 (stratospheric O3), do the rest only in the stratosphere
+!*****************************************************************************
+
+                if (((ztra1_tmp(ipart).gt.3000.).and. &
+                     (pvpart.gt.pvcrit)).or.(mdomainfill.eq.1)) then
+                  nclass_tmp(ipart)=min(int(ran1(idummy)* &
+                       real(nclassunc))+1,nclassunc)
+                  numactiveparticles=numactiveparticles+1
+                  numparticlecount=numparticlecount+1
+                  npoint_tmp(ipart)=numparticlecount
+                  idt_tmp(ipart)=mintime
+                  itra1_tmp(ipart)=itime
+                  itramem_tmp(ipart)=itra1_tmp(ipart)
+                  itrasplit_tmp(ipart)=itra1_tmp(ipart)+ldirect*itsplit
+                  xmass1_tmp(ipart,1)=xmassperparticle
+                  if (mdomainfill.eq.2) xmass1_tmp(ipart,1)= &
+                       xmass1_tmp(ipart,1)*pvpart*48./29.*ozonescale/10.**9
+                else
+                  goto 171
+                endif
+
+
+! Increase numpart, if necessary
+!*******************************
+                numpart_total=max(numpart_total,ipart)
+                goto 173      ! Storage space has been found, stop searching
+              endif
+            end do
+            if (ipart.gt.tmp_size) &
+                 stop 'boundcond_domainfill.f: too many particles required'
+173         minpart=ipart+1
+171         continue
+          end do
+
+
         end do
-
-
       end do
     end do
+
+
+! xm=0.
+! do i=1,numpart_total
+!   if (itra1_tmp(i).eq.itime) xm=xm+xmass1(i,1)
+! end do
+
+!write(*,*) itime,numactiveparticles,numparticlecount,numpart,
+!    +xm,accmasst,xm+accmasst
+
+  end if ! if lroot
+
+! Distribute the number of particles to be released
+! *************************************************
+  call MPI_Bcast(numpart_total, 1, MPI_INTEGER, id_root, mp_comm_used, mp_ierr)
+
+  do i=0, mp_partgroup_np-1
+    numrel_mpi(i) = numpart_total/mp_partgroup_np
+    if (i.lt.mod(numpart_total,mp_partgroup_np)) numrel_mpi(i) = numrel_mpi(i) + 1
   end do
 
-
-  xm=0.
-  do i=1,numpart
-    if (itra1(i).eq.itime) xm=xm+xmass1(i,1)
+! Allocate temporary arrays for receiving processes
+  if (.not.lroot) then 
+    allocate(itra1_tmp(numrel_mpi(mp_partid)),&
+         & npoint_tmp(numrel_mpi(mp_partid)),&
+         & nclass_tmp(numrel_mpi(mp_partid)),&
+         & idt_tmp(numrel_mpi(mp_partid)),&
+         & itramem_tmp(numrel_mpi(mp_partid)),&
+         & itrasplit_tmp(numrel_mpi(mp_partid)),&
+         & xtra1_tmp(numrel_mpi(mp_partid)),&
+         & ytra1_tmp(numrel_mpi(mp_partid)),&
+         & ztra1_tmp(numrel_mpi(mp_partid)),&
+         & xmass1_tmp(numrel_mpi(mp_partid),maxspec))
+      
+! Initialize all particles as non-existent    
+    itra1_tmp(:)=-999999999
+  end if
+
+! Distribute particles
+! Keep track of released particles so far
+  rel_counter = 0
+  mtag = 1000
+
+  do i=0, mp_partgroup_np-1
+
+! For root process, nothing to do except update release count
+    if (i.eq.0) then 
+      rel_counter = rel_counter + numrel_mpi(i)
+      cycle
+    end if
+      
+! Send particles from root to non-root processes
+    if (lroot.and.numrel_mpi(i).gt.0) then
+
+      call MPI_SEND(nclass_tmp(rel_counter+1:rel_counter+numrel_mpi(i)),&
+           &numrel_mpi(i),MPI_INTEGER,i,mtag+1*i,mp_comm_used,mp_ierr)
+
+      call MPI_SEND(npoint_tmp(rel_counter+1:rel_counter+numrel_mpi(i)),&
+           &numrel_mpi(i),MPI_INTEGER,i,mtag+2*i,mp_comm_used,mp_ierr)
+
+      call MPI_SEND(itra1_tmp(rel_counter+1:rel_counter+numrel_mpi(i)),&
+           &numrel_mpi(i),MPI_INTEGER,i,mtag+3*i,mp_comm_used,mp_ierr)
+
+      call MPI_SEND(idt_tmp(rel_counter+1:rel_counter+numrel_mpi(i)),&
+           &numrel_mpi(i),MPI_INTEGER,i,mtag+4*i,mp_comm_used,mp_ierr)
+
+      call MPI_SEND(itramem_tmp(rel_counter+1:rel_counter+numrel_mpi(i)),&
+           &numrel_mpi(i),MPI_INTEGER,i,mtag+5*i,mp_comm_used,mp_ierr)
+
+      call MPI_SEND(itrasplit_tmp(rel_counter+1:rel_counter+numrel_mpi(i)),&
+           &numrel_mpi(i),MPI_INTEGER,i,mtag+6*i,mp_comm_used,mp_ierr)
+
+      call MPI_SEND(xtra1_tmp(rel_counter+1:rel_counter+numrel_mpi(i)),&
+           &numrel_mpi(i),mp_dp,i,mtag+7*i,mp_comm_used,mp_ierr)
+
+      call MPI_SEND(ytra1_tmp(rel_counter+1:rel_counter+numrel_mpi(i)),&
+           &numrel_mpi(i),mp_dp,i,mtag+8*i,mp_comm_used,mp_ierr)
+
+      call MPI_SEND(ztra1_tmp(rel_counter+1:rel_counter+numrel_mpi(i)),&
+           &numrel_mpi(i),mp_sp,i,mtag+9*i,mp_comm_used,mp_ierr)
+
+      do j=1,nspec
+        call MPI_SEND(xmass1_tmp(rel_counter+1:rel_counter+numrel_mpi(i),j),&
+             &numrel_mpi(i),mp_sp,i,mtag+(9+j)*i,mp_comm_used,mp_ierr)
+      end do
+
+! Non-root processes issue receive requests
+    else if (i.eq.mp_partid.and.numrel_mpi(i).gt.0) then 
+      call MPI_RECV(nclass_tmp(1:numrel_mpi(i)),numrel_mpi(i),&
+           &MPI_INTEGER,id_root,mtag+1*i,mp_comm_used,mp_status,mp_ierr)
+
+      call MPI_RECV(npoint_tmp(1:numrel_mpi(i)),numrel_mpi(i),&
+           &MPI_INTEGER,id_root,mtag+2*i,mp_comm_used,mp_status,mp_ierr)
+
+      call MPI_RECV(itra1_tmp(1:numrel_mpi(i)),numrel_mpi(i),&
+           &MPI_INTEGER,id_root,mtag+3*i,mp_comm_used,mp_status,mp_ierr)
+
+      call MPI_RECV(idt_tmp(1:numrel_mpi(i)),numrel_mpi(i),&
+           &MPI_INTEGER,id_root,mtag+4*i,mp_comm_used,mp_status,mp_ierr)
+
+      call MPI_RECV(itramem_tmp(1:numrel_mpi(i)),numrel_mpi(i),&
+           &MPI_INTEGER,id_root,mtag+5*i,mp_comm_used,mp_status,mp_ierr)
+
+      call MPI_RECV(itrasplit_tmp(1:numrel_mpi(i)),numrel_mpi(i),&
+           &MPI_INTEGER,id_root,mtag+6*i,mp_comm_used,mp_status,mp_ierr)
+
+      call MPI_RECV(xtra1_tmp(1:numrel_mpi(i)),numrel_mpi(i),&
+           &mp_dp,id_root,mtag+7*i,mp_comm_used,mp_status,mp_ierr)
+
+      call MPI_RECV(ytra1_tmp(1:numrel_mpi(i)),numrel_mpi(i),&
+           &mp_dp,id_root,mtag+8*i,mp_comm_used,mp_status,mp_ierr)
+
+      call MPI_RECV(ztra1_tmp(1:numrel_mpi(i)),numrel_mpi(i),&
+           &mp_sp,id_root,mtag+9*i,mp_comm_used,mp_status,mp_ierr)
+
+      do j=1,nspec
+        call MPI_RECV(xmass1_tmp(1:numrel_mpi(i),j),numrel_mpi(i),&
+             &mp_sp,id_root,mtag+(9+j)*i,mp_comm_used,mp_status,mp_ierr)
+
+      end do
+    end if
+    rel_counter = rel_counter + numrel_mpi(i)
   end do
 
-  !write(*,*) itime,numactiveparticles,numparticlecount,numpart,
-  !    +xm,accmasst,xm+accmasst
-
-
-  ! If particles shall be dumped, then accumulated masses at the domain boundaries
-  ! must be dumped, too, to be used for later runs
-  !*****************************************************************************
-
-! :TODO: eso parallelize
+! Find free storage space for the new particles.
+! This section is independent of the redistribution scheme used
+! ********************************************************************
+
+! Keep track of released particles so far
+  minpart=1
+    
+! The algorithm should be correct also for root process
+  do i=1, numrel_mpi(mp_partid)
+    do ipart=minpart, maxpart
+      if (itra1(ipart).ne.itime) then
+        itra1(ipart) = itra1_tmp(i)
+        npoint(ipart) = npoint_tmp(i)
+        nclass(ipart) = nclass_tmp(i)
+        idt(ipart) = idt_tmp(i)
+        itramem(ipart) = itramem_tmp(i)
+        itrasplit(ipart) = itrasplit_tmp(i)
+        xtra1(ipart) = xtra1_tmp(i)
+        ytra1(ipart) = ytra1_tmp(i)
+        ztra1(ipart) = ztra1_tmp(i)
+        xmass1(ipart,:) = xmass1_tmp(i,:)
+! Increase numpart, if necessary
+        numpart=max(numpart,ipart)
+        goto 200 ! Storage space has been found, stop searching
+      end if
+    end do
+200 minpart=ipart+1
+  end do
+
+! If particles shall be dumped, then accumulated masses at the domain boundaries
+! must be dumped, too, to be used for later runs
+!*****************************************************************************
+
   if ((ipout.gt.0).and.(itime.eq.loutend)) then
     if (lroot) then
+      call mpif_mtime('iotime',0)
       open(unitboundcond,file=path(2)(1:length(2))//'boundcond.bin', &
            form='unformatted')
@@ -595,6 +788,13 @@
            zcolumn_we,zcolumn_sn,acc_mass_we,acc_mass_sn
       close(unitboundcond)
+      call mpif_mtime('iotime',1)
     end if
   endif
 
+! Deallocate temporary arrays 
+  deallocate(itra1_tmp,npoint_tmp,nclass_tmp,idt_tmp,itramem_tmp,itrasplit_tmp,&
+       & xtra1_tmp,ytra1_tmp,ztra1_tmp,xmass1_tmp,numrel_mpi)
+! numactiveparticles_mpi
+
+
 end subroutine boundcond_domainfill
Index: src/conccalc.f90
===================================================================
--- src/conccalc.f90	(revision fdc0f03d0fd969385acd98d3a3206e9d802172bb)
+++ src/conccalc.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -126,5 +126,5 @@
   !*****************************************************************************
       do ind=indz,indzp
-        rhoprof(ind-indz+1)=p1*rho(ix ,jy ,ind,2) &
+        rhoprof(ind-indz+1)=p1*rho(ix ,jy ,ind,memind(2)) &
              +p2*rho(ixp,jy ,ind,2) &
              +p3*rho(ix ,jyp,ind,2) &
Index: src/concoutput.f90
===================================================================
--- src/concoutput.f90	(revision db712a8ffdd9c478928d0173162055a7c109b178)
+++ src/concoutput.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -626,22 +626,22 @@
 !*************************
 
-  ! do ks=1,nspec
-  !   do kp=1,maxpointspec_act
-  !     do i=1,numreceptor
-  !       creceptor(i,ks)=0.
-  !     end do
-  !     do jy=0,numygrid-1
-  !       do ix=0,numxgrid-1
-  !         do l=1,nclassunc
-  !           do nage=1,nageclass
-  !             do kz=1,numzgrid
-  !               gridunc(ix,jy,kz,ks,kp,l,nage)=0.
-  !             end do
-  !           end do
-  !         end do
-  !       end do
-  !     end do
-  !   end do
-  ! end do
+! do ks=1,nspec
+!   do kp=1,maxpointspec_act
+!     do i=1,numreceptor
+!       creceptor(i,ks)=0.
+!     end do
+!     do jy=0,numygrid-1
+!       do ix=0,numxgrid-1
+!         do l=1,nclassunc
+!           do nage=1,nageclass
+!             do kz=1,numzgrid
+!               gridunc(ix,jy,kz,ks,kp,l,nage)=0.
+!             end do
+!           end do
+!         end do
+!       end do
+!     end do
+!   end do
+! end do
   creceptor(:,:)=0.
   gridunc(:,:,:,:,:,:,:)=0.
Index: src/concoutput_nest_mpi.f90
===================================================================
--- src/concoutput_nest_mpi.f90	(revision 38b7917d85662f40709488fecd7eafd06615a08c)
+++ src/concoutput_nest_mpi.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -105,7 +105,4 @@
 ! Measure execution time
   if (mp_measure_time) call mpif_mtime('iotime',0)
-  !   call cpu_time(mp_root_time_beg)
-  !   mp_root_wtime_beg = mpi_wtime()
-  ! end if
 
   if (verbosity.eq.1) then
Index: src/concoutput_surf.f90
===================================================================
--- src/concoutput_surf.f90	(revision 6a678e3fe206788e9704a724ec54e6d3dcc908e7)
+++ src/concoutput_surf.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -21,40 +21,40 @@
 
 subroutine concoutput_surf(itime,outnum,gridtotalunc,wetgridtotalunc, &
-       drygridtotalunc)
-  !                        i     i          o             o
-  !       o
-  !*****************************************************************************
-  !                                                                            *
-  !     Output of the concentration grid and the receptor concentrations.      *
-  !                                                                            *
-  !     Author: A. Stohl                                                       *
-  !                                                                            *
-  !     24 May 1995                                                            *
-  !                                                                            *
-  !     13 April 1999, Major update: if output size is smaller, dump output    *
-  !                    in sparse matrix format; additional output of           *
-  !                    uncertainty                                             *
-  !                                                                            *
-  !     05 April 2000, Major update: output of age classes; output for backward*
-  !                    runs is time spent in grid cell times total mass of     *
-  !                    species.                                                *
-  !                                                                            *
-  !     17 February 2002, Appropriate dimensions for backward and forward runs *
-  !                       are now specified in file par_mod                    *
-  !                                                                            *
-  !     June 2006, write grid in sparse matrix with a single write command     *
-  !                in order to save disk space                                 *
-  !                                                                            *
-  !     2008 new sparse matrix format                                          *
-  !                                                                            *
-  !*****************************************************************************
-  !                                                                            *
-  ! Variables:                                                                 *
-  ! outnum          number of samples                                          *
-  ! ncells          number of cells with non-zero concentrations               *
-  ! sparse          .true. if in sparse matrix format, else .false.            *
-  ! tot_mu          1 for forward, initial mass mixing ration for backw. runs  *
-  !                                                                            *
-  !*****************************************************************************
+     drygridtotalunc)
+!                        i     i          o             o
+!       o
+!*****************************************************************************
+!                                                                            *
+!     Output of the concentration grid and the receptor concentrations.      *
+!                                                                            *
+!     Author: A. Stohl                                                       *
+!                                                                            *
+!     24 May 1995                                                            *
+!                                                                            *
+!     13 April 1999, Major update: if output size is smaller, dump output    *
+!                    in sparse matrix format; additional output of           *
+!                    uncertainty                                             *
+!                                                                            *
+!     05 April 2000, Major update: output of age classes; output for backward*
+!                    runs is time spent in grid cell times total mass of     *
+!                    species.                                                *
+!                                                                            *
+!     17 February 2002, Appropriate dimensions for backward and forward runs *
+!                       are now specified in file par_mod                    *
+!                                                                            *
+!     June 2006, write grid in sparse matrix with a single write command     *
+!                in order to save disk space                                 *
+!                                                                            *
+!     2008 new sparse matrix format                                          *
+!                                                                            *
+!*****************************************************************************
+!                                                                            *
+! Variables:                                                                 *
+! outnum          number of samples                                          *
+! ncells          number of cells with non-zero concentrations               *
+! sparse          .true. if in sparse matrix format, else .false.            *
+! tot_mu          1 for forward, initial mass mixing ration for backw. runs  *
+!                                                                            *
+!*****************************************************************************
 
   use unc_mod
@@ -73,22 +73,22 @@
   real :: outnum,densityoutrecept(maxreceptor),xl,yl
 
-  !real densityoutgrid(0:numxgrid-1,0:numygrid-1,numzgrid),
-  !    +grid(0:numxgrid-1,0:numygrid-1,numzgrid,maxspec,maxpointspec_act,
-  !    +    maxageclass)
-  !real wetgrid(0:numxgrid-1,0:numygrid-1,maxspec,maxpointspec_act,
-  !    +       maxageclass)
-  !real drygrid(0:numxgrid-1,0:numygrid-1,maxspec,
-  !    +       maxpointspec_act,maxageclass)
-  !real gridsigma(0:numxgrid-1,0:numygrid-1,numzgrid,maxspec,
-  !    +       maxpointspec_act,maxageclass),
-  !    +     drygridsigma(0:numxgrid-1,0:numygrid-1,maxspec,
-  !    +     maxpointspec_act,maxageclass),
-  !    +     wetgridsigma(0:numxgrid-1,0:numygrid-1,maxspec,
-  !    +     maxpointspec_act,maxageclass)
-  !real factor(0:numxgrid-1,0:numygrid-1,numzgrid)
-  !real sparse_dump_r(numxgrid*numygrid*numzgrid)
-  !integer sparse_dump_i(numxgrid*numygrid*numzgrid)
-
-  !real sparse_dump_u(numxgrid*numygrid*numzgrid)
+!real densityoutgrid(0:numxgrid-1,0:numygrid-1,numzgrid),
+!    +grid(0:numxgrid-1,0:numygrid-1,numzgrid,maxspec,maxpointspec_act,
+!    +    maxageclass)
+!real wetgrid(0:numxgrid-1,0:numygrid-1,maxspec,maxpointspec_act,
+!    +       maxageclass)
+!real drygrid(0:numxgrid-1,0:numygrid-1,maxspec,
+!    +       maxpointspec_act,maxageclass)
+!real gridsigma(0:numxgrid-1,0:numygrid-1,numzgrid,maxspec,
+!    +       maxpointspec_act,maxageclass),
+!    +     drygridsigma(0:numxgrid-1,0:numygrid-1,maxspec,
+!    +     maxpointspec_act,maxageclass),
+!    +     wetgridsigma(0:numxgrid-1,0:numygrid-1,maxspec,
+!    +     maxpointspec_act,maxageclass)
+!real factor(0:numxgrid-1,0:numygrid-1,numzgrid)
+!real sparse_dump_r(numxgrid*numygrid*numzgrid)
+!integer sparse_dump_i(numxgrid*numygrid*numzgrid)
+
+!real sparse_dump_u(numxgrid*numygrid*numzgrid)
   real(dep_prec) :: auxgrid(nclassunc)
   real(sp) :: gridtotal,gridsigmatotal,gridtotalunc
@@ -104,11 +104,11 @@
 
   if (verbosity.eq.1) then
-     print*,'inside concoutput_surf '
-     CALL SYSTEM_CLOCK(count_clock)
-     WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
+    print*,'inside concoutput_surf '
+    CALL SYSTEM_CLOCK(count_clock)
+    WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
   endif
 
-  ! Determine current calendar date, needed for the file name
-  !**********************************************************
+! Determine current calendar date, needed for the file name
+!**********************************************************
 
   jul=bdate+real(itime,kind=dp)/86400._dp
@@ -116,14 +116,14 @@
   write(adate,'(i8.8)') jjjjmmdd
   write(atime,'(i6.6)') ihmmss
-  !write(unitdates,'(a)') adate//atime
-
-    open(unitdates,file=path(2)(1:length(2))//'dates', ACCESS='APPEND')
-      write(unitdates,'(a)') adate//atime
-    close(unitdates)
-
-  ! For forward simulations, output fields have dimension MAXSPEC,
-  ! for backward simulations, output fields have dimension MAXPOINT.
-  ! Thus, make loops either about nspec, or about numpoint
-  !*****************************************************************
+!write(unitdates,'(a)') adate//atime
+
+  open(unitdates,file=path(2)(1:length(2))//'dates', ACCESS='APPEND')
+  write(unitdates,'(a)') adate//atime
+  close(unitdates)
+
+! For forward simulations, output fields have dimension MAXSPEC,
+! for backward simulations, output fields have dimension MAXPOINT.
+! Thus, make loops either about nspec, or about numpoint
+!*****************************************************************
 
 
@@ -144,15 +144,15 @@
 
   if (verbosity.eq.1) then
-     print*,'concoutput_surf 2'
-     CALL SYSTEM_CLOCK(count_clock)
-     WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
+    print*,'concoutput_surf 2'
+    CALL SYSTEM_CLOCK(count_clock)
+    WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
   endif
 
-  !*******************************************************************
-  ! Compute air density: sufficiently accurate to take it
-  ! from coarse grid at some time
-  ! Determine center altitude of output layer, and interpolate density
-  ! data to that altitude
-  !*******************************************************************
+!*******************************************************************
+! Compute air density: sufficiently accurate to take it
+! from coarse grid at some time
+! Determine center altitude of output layer, and interpolate density
+! data to that altitude
+!*******************************************************************
 
   do kz=1,numzgrid
@@ -166,5 +166,5 @@
            (height(kzz).gt.halfheight)) goto 46
     end do
-46   kzz=max(min(kzz,nz),2)
+46  kzz=max(min(kzz,nz),2)
     dz1=halfheight-height(kzz-1)
     dz2=height(kzz)-halfheight
@@ -184,35 +184,35 @@
   end do
 
-    do i=1,numreceptor
-      xl=xreceptor(i)
-      yl=yreceptor(i)
-      iix=max(min(nint(xl),nxmin1),0)
-      jjy=max(min(nint(yl),nymin1),0)
-      densityoutrecept(i)=rho(iix,jjy,1,2)
-    end do
-
-
-  ! Output is different for forward and backward simulations
-    do kz=1,numzgrid
-      do jy=0,numygrid-1
-        do ix=0,numxgrid-1
-          if (ldirect.eq.1) then
-            factor3d(ix,jy,kz)=1.e12/volume(ix,jy,kz)/outnum
-          else
-            factor3d(ix,jy,kz)=real(abs(loutaver))/outnum
-          endif
-        end do
+  do i=1,numreceptor
+    xl=xreceptor(i)
+    yl=yreceptor(i)
+    iix=max(min(nint(xl),nxmin1),0)
+    jjy=max(min(nint(yl),nymin1),0)
+    densityoutrecept(i)=rho(iix,jjy,1,2)
+  end do
+
+
+! Output is different for forward and backward simulations
+  do kz=1,numzgrid
+    do jy=0,numygrid-1
+      do ix=0,numxgrid-1
+        if (ldirect.eq.1) then
+          factor3d(ix,jy,kz)=1.e12/volume(ix,jy,kz)/outnum
+        else
+          factor3d(ix,jy,kz)=real(abs(loutaver))/outnum
+        endif
       end do
     end do
-
-  !*********************************************************************
-  ! Determine the standard deviation of the mean concentration or mixing
-  ! ratio (uncertainty of the output) and the dry and wet deposition
-  !*********************************************************************
+  end do
+
+!*********************************************************************
+! Determine the standard deviation of the mean concentration or mixing
+! ratio (uncertainty of the output) and the dry and wet deposition
+!*********************************************************************
 
   if (verbosity.eq.1) then
-     print*,'concoutput_surf 3 (sd)'
-     CALL SYSTEM_CLOCK(count_clock)
-     WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
+    print*,'concoutput_surf 3 (sd)'
+    CALL SYSTEM_CLOCK(count_clock)
+    WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
   endif
   gridtotal=0.
@@ -228,205 +228,205 @@
   do ks=1,nspec
 
-  write(anspec,'(i3.3)') ks
-  if ((iout.eq.1).or.(iout.eq.3).or.(iout.eq.5)) then
-    if (ldirect.eq.1) then
-      open(unitoutgrid,file=path(2)(1:length(2))//'grid_conc_'//adate// &
+    write(anspec,'(i3.3)') ks
+    if ((iout.eq.1).or.(iout.eq.3).or.(iout.eq.5)) then
+      if (ldirect.eq.1) then
+        open(unitoutgrid,file=path(2)(1:length(2))//'grid_conc_'//adate// &
+             atime//'_'//anspec,form='unformatted')
+      else
+        open(unitoutgrid,file=path(2)(1:length(2))//'grid_time_'//adate// &
+             atime//'_'//anspec,form='unformatted')
+      endif
+      write(unitoutgrid) itime
+    endif
+
+    if ((iout.eq.2).or.(iout.eq.3)) then      ! mixing ratio
+      open(unitoutgridppt,file=path(2)(1:length(2))//'grid_pptv_'//adate// &
            atime//'_'//anspec,form='unformatted')
-    else
-      open(unitoutgrid,file=path(2)(1:length(2))//'grid_time_'//adate// &
-           atime//'_'//anspec,form='unformatted')
+
+      write(unitoutgridppt) itime
     endif
-     write(unitoutgrid) itime
-   endif
-
-  if ((iout.eq.2).or.(iout.eq.3)) then      ! mixing ratio
-   open(unitoutgridppt,file=path(2)(1:length(2))//'grid_pptv_'//adate// &
-        atime//'_'//anspec,form='unformatted')
-
-    write(unitoutgridppt) itime
-  endif
-
-  do kp=1,maxpointspec_act
-  do nage=1,nageclass
-
-    do jy=0,numygrid-1
-      do ix=0,numxgrid-1
-
-  ! WET DEPOSITION
-        if ((WETDEP).and.(ldirect.gt.0)) then
-            do l=1,nclassunc
-              auxgrid(l)=wetgridunc(ix,jy,ks,kp,l,nage)
-            end do
-            call mean(auxgrid,wetgrid(ix,jy), &
-                 wetgridsigma(ix,jy),nclassunc)
-  ! Multiply by number of classes to get total concentration
-            wetgrid(ix,jy)=wetgrid(ix,jy) &
-                 *nclassunc
-            wetgridtotal=wetgridtotal+wetgrid(ix,jy)
-  ! Calculate standard deviation of the mean
-            wetgridsigma(ix,jy)= &
-                 wetgridsigma(ix,jy)* &
-                 sqrt(real(nclassunc))
-            wetgridsigmatotal=wetgridsigmatotal+ &
-                 wetgridsigma(ix,jy)
+
+    do kp=1,maxpointspec_act
+      do nage=1,nageclass
+
+        do jy=0,numygrid-1
+          do ix=0,numxgrid-1
+
+! WET DEPOSITION
+            if ((WETDEP).and.(ldirect.gt.0)) then
+              do l=1,nclassunc
+                auxgrid(l)=wetgridunc(ix,jy,ks,kp,l,nage)
+              end do
+              call mean(auxgrid,wetgrid(ix,jy), &
+                   wetgridsigma(ix,jy),nclassunc)
+! Multiply by number of classes to get total concentration
+              wetgrid(ix,jy)=wetgrid(ix,jy) &
+                   *nclassunc
+              wetgridtotal=wetgridtotal+wetgrid(ix,jy)
+! Calculate standard deviation of the mean
+              wetgridsigma(ix,jy)= &
+                   wetgridsigma(ix,jy)* &
+                   sqrt(real(nclassunc))
+              wetgridsigmatotal=wetgridsigmatotal+ &
+                   wetgridsigma(ix,jy)
+            endif
+
+! DRY DEPOSITION
+            if ((DRYDEP).and.(ldirect.gt.0)) then
+              do l=1,nclassunc
+                auxgrid(l)=drygridunc(ix,jy,ks,kp,l,nage)
+              end do
+              call mean(auxgrid,drygrid(ix,jy), &
+                   drygridsigma(ix,jy),nclassunc)
+! Multiply by number of classes to get total concentration
+              drygrid(ix,jy)=drygrid(ix,jy)* &
+                   nclassunc
+              drygridtotal=drygridtotal+drygrid(ix,jy)
+! Calculate standard deviation of the mean
+              drygridsigma(ix,jy)= &
+                   drygridsigma(ix,jy)* &
+                   sqrt(real(nclassunc))
+125           drygridsigmatotal=drygridsigmatotal+ &
+                   drygridsigma(ix,jy)
+            endif
+
+! CONCENTRATION OR MIXING RATIO
+            do kz=1,numzgrid
+              do l=1,nclassunc
+                auxgrid(l)=gridunc(ix,jy,kz,ks,kp,l,nage)
+              end do
+              call mean(auxgrid,grid(ix,jy,kz), &
+                   gridsigma(ix,jy,kz),nclassunc)
+! Multiply by number of classes to get total concentration
+              grid(ix,jy,kz)= &
+                   grid(ix,jy,kz)*nclassunc
+              gridtotal=gridtotal+grid(ix,jy,kz)
+! Calculate standard deviation of the mean
+              gridsigma(ix,jy,kz)= &
+                   gridsigma(ix,jy,kz)* &
+                   sqrt(real(nclassunc))
+              gridsigmatotal=gridsigmatotal+ &
+                   gridsigma(ix,jy,kz)
+            end do
+          end do
+        end do
+
+
+!*******************************************************************
+! Generate output: may be in concentration (ng/m3) or in mixing
+! ratio (ppt) or both
+! Output the position and the values alternated multiplied by
+! 1 or -1, first line is number of values, number of positions
+! For backward simulations, the unit is seconds, stored in grid_time
+!*******************************************************************
+
+        if (verbosity.eq.1) then
+          print*,'concoutput_surf 4 (output)'
+          CALL SYSTEM_CLOCK(count_clock)
+          WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
         endif
 
-  ! DRY DEPOSITION
-        if ((DRYDEP).and.(ldirect.gt.0)) then
-            do l=1,nclassunc
-              auxgrid(l)=drygridunc(ix,jy,ks,kp,l,nage)
-            end do
-            call mean(auxgrid,drygrid(ix,jy), &
-                 drygridsigma(ix,jy),nclassunc)
-  ! Multiply by number of classes to get total concentration
-            drygrid(ix,jy)=drygrid(ix,jy)* &
-                 nclassunc
-            drygridtotal=drygridtotal+drygrid(ix,jy)
-  ! Calculate standard deviation of the mean
-            drygridsigma(ix,jy)= &
-                 drygridsigma(ix,jy)* &
-                 sqrt(real(nclassunc))
-125         drygridsigmatotal=drygridsigmatotal+ &
-                 drygridsigma(ix,jy)
-        endif
-
-  ! CONCENTRATION OR MIXING RATIO
-        do kz=1,numzgrid
-            do l=1,nclassunc
-              auxgrid(l)=gridunc(ix,jy,kz,ks,kp,l,nage)
-            end do
-            call mean(auxgrid,grid(ix,jy,kz), &
-                 gridsigma(ix,jy,kz),nclassunc)
-  ! Multiply by number of classes to get total concentration
-            grid(ix,jy,kz)= &
-                 grid(ix,jy,kz)*nclassunc
-            gridtotal=gridtotal+grid(ix,jy,kz)
-  ! Calculate standard deviation of the mean
-            gridsigma(ix,jy,kz)= &
-                 gridsigma(ix,jy,kz)* &
-                 sqrt(real(nclassunc))
-            gridsigmatotal=gridsigmatotal+ &
-                 gridsigma(ix,jy,kz)
-        end do
-      end do
-    end do
-
-
-  !*******************************************************************
-  ! Generate output: may be in concentration (ng/m3) or in mixing
-  ! ratio (ppt) or both
-  ! Output the position and the values alternated multiplied by
-  ! 1 or -1, first line is number of values, number of positions
-  ! For backward simulations, the unit is seconds, stored in grid_time
-  !*******************************************************************
-
-  if (verbosity.eq.1) then
-     print*,'concoutput_surf 4 (output)'
-     CALL SYSTEM_CLOCK(count_clock)
-     WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
-  endif
-
-  ! Concentration output
-  !*********************
-
-  if ((iout.eq.1).or.(iout.eq.3).or.(iout.eq.5)) then
-
-  if (verbosity.eq.1) then
-     print*,'concoutput_surf (Wet deposition)'
-     CALL SYSTEM_CLOCK(count_clock)
-     WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
-  endif
-
-  ! Wet deposition
-         sp_count_i=0
-         sp_count_r=0
-         sp_fact=-1.
-         sp_zer=.true.
-         if ((ldirect.eq.1).and.(WETDEP)) then
-         do jy=0,numygrid-1
-            do ix=0,numxgrid-1
-  ! concentraion greater zero
-              if (wetgrid(ix,jy).gt.smallnum) then
-                 if (sp_zer.eqv..true.) then ! first non zero value
+! Concentration output
+!*********************
+
+        if ((iout.eq.1).or.(iout.eq.3).or.(iout.eq.5)) then
+
+          if (verbosity.eq.1) then
+            print*,'concoutput_surf (Wet deposition)'
+            CALL SYSTEM_CLOCK(count_clock)
+            WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
+          endif
+
+! Wet deposition
+          sp_count_i=0
+          sp_count_r=0
+          sp_fact=-1.
+          sp_zer=.true.
+          if ((ldirect.eq.1).and.(WETDEP)) then
+            do jy=0,numygrid-1
+              do ix=0,numxgrid-1
+! concentraion greater zero
+                if (wetgrid(ix,jy).gt.smallnum) then
+                  if (sp_zer.eqv..true.) then ! first non zero value
                     sp_count_i=sp_count_i+1
                     sparse_dump_i(sp_count_i)=ix+jy*numxgrid
                     sp_zer=.false.
                     sp_fact=sp_fact*(-1.)
-                 endif
-                 sp_count_r=sp_count_r+1
-                 sparse_dump_r(sp_count_r)= &
-                      sp_fact*1.e12*wetgrid(ix,jy)/area(ix,jy)
-                 sparse_dump_u(sp_count_r)= &
-                      1.e12*wetgridsigma(ix,jy)/area(ix,jy)
-              else ! concentration is zero
+                  endif
+                  sp_count_r=sp_count_r+1
+                  sparse_dump_r(sp_count_r)= &
+                       sp_fact*1.e12*wetgrid(ix,jy)/area(ix,jy)
+                  sparse_dump_u(sp_count_r)= &
+                       1.e12*wetgridsigma(ix,jy)/area(ix,jy)
+                else ! concentration is zero
                   sp_zer=.true.
-              endif
-            end do
-         end do
-         else
+                endif
+              end do
+            end do
+          else
             sp_count_i=0
             sp_count_r=0
-         endif
-         write(unitoutgrid) sp_count_i
-         write(unitoutgrid) (sparse_dump_i(i),i=1,sp_count_i)
-         write(unitoutgrid) sp_count_r
-         write(unitoutgrid) (sparse_dump_r(i),i=1,sp_count_r)
+          endif
+          write(unitoutgrid) sp_count_i
+          write(unitoutgrid) (sparse_dump_i(i),i=1,sp_count_i)
+          write(unitoutgrid) sp_count_r
+          write(unitoutgrid) (sparse_dump_r(i),i=1,sp_count_r)
 !         write(unitoutgrid) (sparse_dump_u(i),i=1,sp_count_r)
 
-  if (verbosity.eq.1) then
-     print*,'concoutput_surf (Dry deposition)'
-     CALL SYSTEM_CLOCK(count_clock)
-     WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
-  endif
-  ! Dry deposition
-         sp_count_i=0
-         sp_count_r=0
-         sp_fact=-1.
-         sp_zer=.true.
-         if ((ldirect.eq.1).and.(DRYDEP)) then
-          do jy=0,numygrid-1
-            do ix=0,numxgrid-1
-              if (drygrid(ix,jy).gt.smallnum) then
-                 if (sp_zer.eqv..true.) then ! first non zero value
+          if (verbosity.eq.1) then
+            print*,'concoutput_surf (Dry deposition)'
+            CALL SYSTEM_CLOCK(count_clock)
+            WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
+          endif
+! Dry deposition
+          sp_count_i=0
+          sp_count_r=0
+          sp_fact=-1.
+          sp_zer=.true.
+          if ((ldirect.eq.1).and.(DRYDEP)) then
+            do jy=0,numygrid-1
+              do ix=0,numxgrid-1
+                if (drygrid(ix,jy).gt.smallnum) then
+                  if (sp_zer.eqv..true.) then ! first non zero value
                     sp_count_i=sp_count_i+1
                     sparse_dump_i(sp_count_i)=ix+jy*numxgrid
                     sp_zer=.false.
                     sp_fact=sp_fact*(-1.)
-                 endif
-                 sp_count_r=sp_count_r+1
-                 sparse_dump_r(sp_count_r)= &
-                      sp_fact* &
-                      1.e12*drygrid(ix,jy)/area(ix,jy)
+                  endif
+                  sp_count_r=sp_count_r+1
+                  sparse_dump_r(sp_count_r)= &
+                       sp_fact* &
+                       1.e12*drygrid(ix,jy)/area(ix,jy)
                   sparse_dump_u(sp_count_r)= &
-                      1.e12*drygridsigma(ix,jy)/area(ix,jy)
-              else ! concentration is zero
+                       1.e12*drygridsigma(ix,jy)/area(ix,jy)
+                else ! concentration is zero
                   sp_zer=.true.
-              endif
-            end do
-          end do
-         else
+                endif
+              end do
+            end do
+          else
             sp_count_i=0
             sp_count_r=0
-         endif
-         write(unitoutgrid) sp_count_i
-         write(unitoutgrid) (sparse_dump_i(i),i=1,sp_count_i)
-         write(unitoutgrid) sp_count_r
-         write(unitoutgrid) (sparse_dump_r(i),i=1,sp_count_r)
+          endif
+          write(unitoutgrid) sp_count_i
+          write(unitoutgrid) (sparse_dump_i(i),i=1,sp_count_i)
+          write(unitoutgrid) sp_count_r
+          write(unitoutgrid) (sparse_dump_r(i),i=1,sp_count_r)
 !         write(unitoutgrid) (sparse_dump_u(i),i=1,sp_count_r)
 
-  if (verbosity.eq.1) then
-     print*,'concoutput_surf (Concentrations)'
-     CALL SYSTEM_CLOCK(count_clock)
-     WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
-  endif
-
-  ! Concentrations
-
-  ! surf_only write only 1st layer 
-
-         sp_count_i=0
-         sp_count_r=0
-         sp_fact=-1.
-         sp_zer=.true.
+          if (verbosity.eq.1) then
+            print*,'concoutput_surf (Concentrations)'
+            CALL SYSTEM_CLOCK(count_clock)
+            WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
+          endif
+
+! Concentrations
+
+! surf_only write only 1st layer 
+
+          sp_count_i=0
+          sp_count_r=0
+          sp_fact=-1.
+          sp_zer=.true.
           do kz=1,1
             do jy=0,numygrid-1
@@ -440,41 +440,41 @@
                     sp_fact=sp_fact*(-1.)
                   endif
-                   sp_count_r=sp_count_r+1
-                   sparse_dump_r(sp_count_r)= &
-                        sp_fact* &
-                        grid(ix,jy,kz)* &
-                        factor3d(ix,jy,kz)/tot_mu(ks,kp)
-  !                 if ((factor(ix,jy,kz)/tot_mu(ks,kp)).eq.0)
-  !    +              write (*,*) factor(ix,jy,kz),tot_mu(ks,kp),ks,kp
-                   sparse_dump_u(sp_count_r)= &
-                        gridsigma(ix,jy,kz)* &
-                        factor3d(ix,jy,kz)/tot_mu(ks,kp)
+                  sp_count_r=sp_count_r+1
+                  sparse_dump_r(sp_count_r)= &
+                       sp_fact* &
+                       grid(ix,jy,kz)* &
+                       factor3d(ix,jy,kz)/tot_mu(ks,kp)
+!                 if ((factor(ix,jy,kz)/tot_mu(ks,kp)).eq.0)
+!    +              write (*,*) factor(ix,jy,kz),tot_mu(ks,kp),ks,kp
+                  sparse_dump_u(sp_count_r)= &
+                       gridsigma(ix,jy,kz)* &
+                       factor3d(ix,jy,kz)/tot_mu(ks,kp)
                 else ! concentration is zero
                   sp_zer=.true.
                 endif
-             end do
-           end do
-         end do
-         write(unitoutgrid) sp_count_i
-         write(unitoutgrid) (sparse_dump_i(i),i=1,sp_count_i)
-         write(unitoutgrid) sp_count_r
-         write(unitoutgrid) (sparse_dump_r(i),i=1,sp_count_r)
+              end do
+            end do
+          end do
+          write(unitoutgrid) sp_count_i
+          write(unitoutgrid) (sparse_dump_i(i),i=1,sp_count_i)
+          write(unitoutgrid) sp_count_r
+          write(unitoutgrid) (sparse_dump_r(i),i=1,sp_count_r)
 !         write(unitoutgrid) (sparse_dump_u(i),i=1,sp_count_r)
 
-  endif !  concentration output
-
-  ! Mixing ratio output
-  !********************
-
-  if ((iout.eq.2).or.(iout.eq.3)) then      ! mixing ratio
-
-  ! Wet deposition
-         sp_count_i=0
-         sp_count_r=0
-         sp_fact=-1.
-         sp_zer=.true.
-         if ((ldirect.eq.1).and.(WETDEP)) then
-          do jy=0,numygrid-1
-            do ix=0,numxgrid-1
+        endif !  concentration output
+
+! Mixing ratio output
+!********************
+
+        if ((iout.eq.2).or.(iout.eq.3)) then      ! mixing ratio
+
+! Wet deposition
+          sp_count_i=0
+          sp_count_r=0
+          sp_fact=-1.
+          sp_zer=.true.
+          if ((ldirect.eq.1).and.(WETDEP)) then
+            do jy=0,numygrid-1
+              do ix=0,numxgrid-1
                 if (wetgrid(ix,jy).gt.smallnum) then
                   if (sp_zer.eqv..true.) then ! first non zero value
@@ -484,35 +484,35 @@
                     sp_zer=.false.
                     sp_fact=sp_fact*(-1.)
-                 endif
-                 sp_count_r=sp_count_r+1
-                 sparse_dump_r(sp_count_r)= &
-                      sp_fact* &
-                      1.e12*wetgrid(ix,jy)/area(ix,jy)
-                 sparse_dump_u(sp_count_r)= &
-                      1.e12*wetgridsigma(ix,jy)/area(ix,jy)
-              else ! concentration is zero
+                  endif
+                  sp_count_r=sp_count_r+1
+                  sparse_dump_r(sp_count_r)= &
+                       sp_fact* &
+                       1.e12*wetgrid(ix,jy)/area(ix,jy)
+                  sparse_dump_u(sp_count_r)= &
+                       1.e12*wetgridsigma(ix,jy)/area(ix,jy)
+                else ! concentration is zero
                   sp_zer=.true.
-              endif
-            end do
-          end do
-         else
-           sp_count_i=0
-           sp_count_r=0
-         endif
-         write(unitoutgridppt) sp_count_i
-         write(unitoutgridppt) (sparse_dump_i(i),i=1,sp_count_i)
-         write(unitoutgridppt) sp_count_r
-         write(unitoutgridppt) (sparse_dump_r(i),i=1,sp_count_r)
+                endif
+              end do
+            end do
+          else
+            sp_count_i=0
+            sp_count_r=0
+          endif
+          write(unitoutgridppt) sp_count_i
+          write(unitoutgridppt) (sparse_dump_i(i),i=1,sp_count_i)
+          write(unitoutgridppt) sp_count_r
+          write(unitoutgridppt) (sparse_dump_r(i),i=1,sp_count_r)
 !         write(unitoutgridppt) (sparse_dump_u(i),i=1,sp_count_r)
 
 
-  ! Dry deposition
-         sp_count_i=0
-         sp_count_r=0
-         sp_fact=-1.
-         sp_zer=.true.
-         if ((ldirect.eq.1).and.(DRYDEP)) then
-          do jy=0,numygrid-1
-            do ix=0,numxgrid-1
+! Dry deposition
+          sp_count_i=0
+          sp_count_r=0
+          sp_fact=-1.
+          sp_zer=.true.
+          if ((ldirect.eq.1).and.(DRYDEP)) then
+            do jy=0,numygrid-1
+              do ix=0,numxgrid-1
                 if (drygrid(ix,jy).gt.smallnum) then
                   if (sp_zer.eqv..true.) then ! first non zero value
@@ -522,35 +522,35 @@
                     sp_zer=.false.
                     sp_fact=sp_fact*(-1)
-                 endif
-                 sp_count_r=sp_count_r+1
-                 sparse_dump_r(sp_count_r)= &
-                      sp_fact* &
-                      1.e12*drygrid(ix,jy)/area(ix,jy)
-                 sparse_dump_u(sp_count_r)= &
-                      1.e12*drygridsigma(ix,jy)/area(ix,jy)
-              else ! concentration is zero
+                  endif
+                  sp_count_r=sp_count_r+1
+                  sparse_dump_r(sp_count_r)= &
+                       sp_fact* &
+                       1.e12*drygrid(ix,jy)/area(ix,jy)
+                  sparse_dump_u(sp_count_r)= &
+                       1.e12*drygridsigma(ix,jy)/area(ix,jy)
+                else ! concentration is zero
                   sp_zer=.true.
-              endif
-            end do
-          end do
-         else
-           sp_count_i=0
-           sp_count_r=0
-         endif
-         write(unitoutgridppt) sp_count_i
-         write(unitoutgridppt) (sparse_dump_i(i),i=1,sp_count_i)
-         write(unitoutgridppt) sp_count_r
-         write(unitoutgridppt) (sparse_dump_r(i),i=1,sp_count_r)
+                endif
+              end do
+            end do
+          else
+            sp_count_i=0
+            sp_count_r=0
+          endif
+          write(unitoutgridppt) sp_count_i
+          write(unitoutgridppt) (sparse_dump_i(i),i=1,sp_count_i)
+          write(unitoutgridppt) sp_count_r
+          write(unitoutgridppt) (sparse_dump_r(i),i=1,sp_count_r)
 !         write(unitoutgridppt) (sparse_dump_u(i),i=1,sp_count_r)
 
 
-  ! Mixing ratios
-
-  ! surf_only write only 1st layer 
-
-         sp_count_i=0
-         sp_count_r=0
-         sp_fact=-1.
-         sp_zer=.true.
+! Mixing ratios
+
+! surf_only write only 1st layer 
+
+          sp_count_i=0
+          sp_count_r=0
+          sp_fact=-1.
+          sp_zer=.true.
           do kz=1,1
             do jy=0,numygrid-1
@@ -563,31 +563,31 @@
                     sp_zer=.false.
                     sp_fact=sp_fact*(-1.)
-                 endif
-                 sp_count_r=sp_count_r+1
-                 sparse_dump_r(sp_count_r)= &
-                      sp_fact* &
-                      1.e12*grid(ix,jy,kz) &
-                      /volume(ix,jy,kz)/outnum* &
-                      weightair/weightmolar(ks)/densityoutgrid(ix,jy,kz)
-                 sparse_dump_u(sp_count_r)= &
-                      1.e12*gridsigma(ix,jy,kz)/volume(ix,jy,kz)/ &
-                      outnum*weightair/weightmolar(ks)/ &
-                      densityoutgrid(ix,jy,kz)
-              else ! concentration is zero
+                  endif
+                  sp_count_r=sp_count_r+1
+                  sparse_dump_r(sp_count_r)= &
+                       sp_fact* &
+                       1.e12*grid(ix,jy,kz) &
+                       /volume(ix,jy,kz)/outnum* &
+                       weightair/weightmolar(ks)/densityoutgrid(ix,jy,kz)
+                  sparse_dump_u(sp_count_r)= &
+                       1.e12*gridsigma(ix,jy,kz)/volume(ix,jy,kz)/ &
+                       outnum*weightair/weightmolar(ks)/ &
+                       densityoutgrid(ix,jy,kz)
+                else ! concentration is zero
                   sp_zer=.true.
-              endif
+                endif
               end do
             end do
           end do
-         write(unitoutgridppt) sp_count_i
-         write(unitoutgridppt) (sparse_dump_i(i),i=1,sp_count_i)
-         write(unitoutgridppt) sp_count_r
-         write(unitoutgridppt) (sparse_dump_r(i),i=1,sp_count_r)
+          write(unitoutgridppt) sp_count_i
+          write(unitoutgridppt) (sparse_dump_i(i),i=1,sp_count_i)
+          write(unitoutgridppt) sp_count_r
+          write(unitoutgridppt) (sparse_dump_r(i),i=1,sp_count_r)
 !         write(unitoutgridppt) (sparse_dump_u(i),i=1,sp_count_r)
 
-      endif ! output for ppt
-
-  end do
-  end do
+        endif ! output for ppt
+
+      end do
+    end do
 
     close(unitoutgridppt)
@@ -602,40 +602,41 @@
        drygridtotal
 
-  ! Dump of receptor concentrations
-
-    if (numreceptor.gt.0 .and. (iout.eq.2 .or. iout.eq.3)  ) then
-      write(unitoutreceptppt) itime
-      do ks=1,nspec
-        write(unitoutreceptppt) (1.e12*creceptor(i,ks)/outnum* &
-             weightair/weightmolar(ks)/densityoutrecept(i),i=1,numreceptor)
+! Dump of receptor concentrations
+
+  if (numreceptor.gt.0 .and. (iout.eq.2 .or. iout.eq.3)  ) then
+    write(unitoutreceptppt) itime
+    do ks=1,nspec
+      write(unitoutreceptppt) (1.e12*creceptor(i,ks)/outnum* &
+           weightair/weightmolar(ks)/densityoutrecept(i),i=1,numreceptor)
+    end do
+  endif
+
+! Dump of receptor concentrations
+
+  if (numreceptor.gt.0) then
+    write(unitoutrecept) itime
+    do ks=1,nspec
+      write(unitoutrecept) (1.e12*creceptor(i,ks)/outnum, &
+           i=1,numreceptor)
+    end do
+  endif
+
+
+
+! Reinitialization of grid
+!*************************
+
+  do ks=1,nspec
+    do kp=1,maxpointspec_act
+      do i=1,numreceptor
+        creceptor(i,ks)=0.
       end do
-    endif
-
-  ! Dump of receptor concentrations
-
-    if (numreceptor.gt.0) then
-      write(unitoutrecept) itime
-      do ks=1,nspec
-        write(unitoutrecept) (1.e12*creceptor(i,ks)/outnum, &
-             i=1,numreceptor)
-      end do
-    endif
-
-
-
-  ! Reinitialization of grid
-  !*************************
-
-  do ks=1,nspec
-  do kp=1,maxpointspec_act
-    do i=1,numreceptor
-      creceptor(i,ks)=0.
-    end do
-    do jy=0,numygrid-1
-      do ix=0,numxgrid-1
-        do l=1,nclassunc
-          do nage=1,nageclass
-            do kz=1,numzgrid
-              gridunc(ix,jy,kz,ks,kp,l,nage)=0.
+      do jy=0,numygrid-1
+        do ix=0,numxgrid-1
+          do l=1,nclassunc
+            do nage=1,nageclass
+              do kz=1,numzgrid
+                gridunc(ix,jy,kz,ks,kp,l,nage)=0.
+              end do
             end do
           end do
@@ -644,5 +645,4 @@
     end do
   end do
-  end do
 
 
Index: src/init_domainfill_mpi.f90
===================================================================
--- src/init_domainfill_mpi.f90	(revision 0f7835d03c332f5ff00577f23b0a0d791e42b9dc)
+++ src/init_domainfill_mpi.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -47,4 +47,14 @@
 !                                                                            *
 !*****************************************************************************
+! MPI version:
+!
+!   -Root process allocates temporary arrays holding properties for
+!    all particles in the simulation
+!   -An index array is used to assign 1st particle to 1st process, 2nd particle
+!    to 2nd process and so on so that they are evenly distibuted geographically
+!   -Inititialization for domain-filling is done as in the serial code
+!   -Root process distributes particles evenly to other processes
+! 
+!*****************************************************************************
 
   use point_mod
@@ -56,5 +66,6 @@
   implicit none
 
-  integer :: j,ix,jy,kz,ncolumn,numparttot
+! ncolumn_mpi,numparttot_mpi        ncolumn,numparttot per process
+  integer :: j,ix,jy,kz,ncolumn,numparttot,ncolumn_mpi,numparttot_mpi, arr_size
   real :: gridarea(0:nymax-1),pp(nzmax),ylat,ylatp,ylatm,hzone
   real :: cosfactm,cosfactp,deltacol,dz1,dz2,dz,pnew,fractus
@@ -66,7 +77,10 @@
 
   integer :: idummy = -11
+  integer,allocatable,dimension(:) :: idx ! index array
+  integer :: stride
+  integer, parameter :: nullsize=0
   logical :: first_call=.true.
 
-  ! Use different seed for each process
+! Use different seed for each process ! TODO: not needed anymore
   if (first_call) then
     idummy=idummy+mp_seed
@@ -102,53 +116,89 @@
 
 
+! This section only done by the root process
+!*******************************************
+  if (lroot) then
+! Arrays for particles to be released. Add a small number to npart(1) in case of
+! round-off errors
+    arr_size = npart(1) + mp_np
+    allocate(itra1_tmp(arr_size),npoint_tmp(arr_size),nclass_tmp(arr_size),&
+         & idt_tmp(arr_size),itramem_tmp(arr_size),itrasplit_tmp(arr_size),&
+         & xtra1_tmp(arr_size),ytra1_tmp(arr_size),ztra1_tmp(arr_size),&
+         & xmass1_tmp(arr_size, maxspec))
+
+! Index array for particles. This is to avoid having particles
+! near edges of domain all on one process.
+!****************************************************************************
+    allocate(idx(npart(1)))
+    stride = npart(1)/mp_partgroup_np
+
+    jj=0
+    do j=1, stride
+      do i=0, mp_partgroup_np-1
+        jj = jj+1
+        if (jj.gt.npart(1)) exit
+        idx(jj) = i*stride+j
+      end do
+    end do
+
+! Add extra indices if npart(1) not evenly divisible by number of processes
+    do i=1, mod(npart(1),mp_partgroup_np)
+      jj = jj+1
+      if (jj.gt.npart(1)) exit
+      idx(jj) = jj
+    end do
+
+! Initialize all particles as non-existent    
+    itra1_tmp(:)=-999999999
+
 ! Calculate area of grid cell with formula M=2*pi*R*h*dx/360,
 ! see Netz, Formeln der Mathematik, 5. Auflage (1983), p.90
 !************************************************************
 
-  do jy=ny_sn(1),ny_sn(2)      ! loop about latitudes
-    ylat=ylat0+real(jy)*dy
-    ylatp=ylat+0.5*dy
-    ylatm=ylat-0.5*dy
-    if ((ylatm.lt.0).and.(ylatp.gt.0.)) then
-      hzone=1./dyconst
-    else
+    do jy=ny_sn(1),ny_sn(2)      ! loop about latitudes
+      ylat=ylat0+real(jy)*dy
+      ylatp=ylat+0.5*dy
+      ylatm=ylat-0.5*dy
+      if ((ylatm.lt.0).and.(ylatp.gt.0.)) then
+        hzone=1./dyconst
+      else
+        cosfactp=cos(ylatp*pih)*r_earth
+        cosfactm=cos(ylatm*pih)*r_earth
+        if (cosfactp.lt.cosfactm) then
+          hzone=sqrt(r_earth**2-cosfactp**2)- &
+               sqrt(r_earth**2-cosfactm**2)
+        else
+          hzone=sqrt(r_earth**2-cosfactm**2)- &
+               sqrt(r_earth**2-cosfactp**2)
+        endif
+      endif
+      gridarea(jy)=2.*pi*r_earth*hzone*dx/360.
+    end do
+
+! Do the same for the south pole
+
+    if (sglobal) then
+      ylat=ylat0
+      ylatp=ylat+0.5*dy
+      ylatm=ylat
+      cosfactm=0.
       cosfactp=cos(ylatp*pih)*r_earth
+      hzone=sqrt(r_earth**2-cosfactm**2)- &
+           sqrt(r_earth**2-cosfactp**2)
+      gridarea(0)=2.*pi*r_earth*hzone*dx/360.
+    endif
+
+! Do the same for the north pole
+
+    if (nglobal) then
+      ylat=ylat0+real(nymin1)*dy
+      ylatp=ylat
+      ylatm=ylat-0.5*dy
+      cosfactp=0.
       cosfactm=cos(ylatm*pih)*r_earth
-      if (cosfactp.lt.cosfactm) then
-        hzone=sqrt(r_earth**2-cosfactp**2)- &
-             sqrt(r_earth**2-cosfactm**2)
-      else
-        hzone=sqrt(r_earth**2-cosfactm**2)- &
-             sqrt(r_earth**2-cosfactp**2)
-      endif
+      hzone=sqrt(r_earth**2-cosfactp**2)- &
+           sqrt(r_earth**2-cosfactm**2)
+      gridarea(nymin1)=2.*pi*r_earth*hzone*dx/360.
     endif
-    gridarea(jy)=2.*pi*r_earth*hzone*dx/360.
-  end do
-
-! Do the same for the south pole
-
-  if (sglobal) then
-    ylat=ylat0
-    ylatp=ylat+0.5*dy
-    ylatm=ylat
-    cosfactm=0.
-    cosfactp=cos(ylatp*pih)*r_earth
-    hzone=sqrt(r_earth**2-cosfactm**2)- &
-         sqrt(r_earth**2-cosfactp**2)
-    gridarea(0)=2.*pi*r_earth*hzone*dx/360.
-  endif
-
-! Do the same for the north pole
-
-  if (nglobal) then
-    ylat=ylat0+real(nymin1)*dy
-    ylatp=ylat
-    ylatm=ylat-0.5*dy
-    cosfactp=0.
-    cosfactm=cos(ylatm*pih)*r_earth
-    hzone=sqrt(r_earth**2-cosfactp**2)- &
-         sqrt(r_earth**2-cosfactm**2)
-    gridarea(nymin1)=2.*pi*r_earth*hzone*dx/360.
-  endif
 
 
@@ -156,33 +206,32 @@
 !*********************************************************************
 
-  colmasstotal=0.
-  do jy=ny_sn(1),ny_sn(2)          ! loop about latitudes
-    do ix=nx_we(1),nx_we(2)      ! loop about longitudes
-      pp(1)=rho(ix,jy,1,1)*r_air*tt(ix,jy,1,1)
-      pp(nz)=rho(ix,jy,nz,1)*r_air*tt(ix,jy,nz,1)
-      ! Each MPI process is assigned an equal share of particles
-      colmass(ix,jy)=(pp(1)-pp(nz))/ga*gridarea(jy)/mp_partgroup_np
-      colmasstotal=colmasstotal+colmass(ix,jy)
-
-    end do
-  end do
-
-  if (lroot) write(*,*) 'Atm. mass: ',colmasstotal
-
-
-  if (ipin.eq.0) numpart=0
+    colmasstotal=0.
+    do jy=ny_sn(1),ny_sn(2)          ! loop about latitudes
+      do ix=nx_we(1),nx_we(2)      ! loop about longitudes
+        pp(1)=rho(ix,jy,1,1)*r_air*tt(ix,jy,1,1)
+        pp(nz)=rho(ix,jy,nz,1)*r_air*tt(ix,jy,nz,1)
+        colmass(ix,jy)=(pp(1)-pp(nz))/ga*gridarea(jy)
+        colmasstotal=colmasstotal+colmass(ix,jy)
+
+      end do
+    end do
+
+    write(*,*) 'Atm. mass: ',colmasstotal
+
+
+    if (ipin.eq.0) numpart=0
 
 ! Determine the particle positions
 !*********************************
 
-  numparttot=0
-  numcolumn=0
-  do jy=ny_sn(1),ny_sn(2)      ! loop about latitudes
-    ylat=ylat0+real(jy)*dy
-    do ix=nx_we(1),nx_we(2)      ! loop about longitudes
-      ncolumn=nint(0.999*real(npart(1)/mp_partgroup_np)*colmass(ix,jy)/ &
-           colmasstotal)
-      if (ncolumn.eq.0) goto 30
-      if (ncolumn.gt.numcolumn) numcolumn=ncolumn
+    numparttot=0
+    numcolumn=0
+    do jy=ny_sn(1),ny_sn(2)      ! loop about latitudes
+      ylat=ylat0+real(jy)*dy
+      do ix=nx_we(1),nx_we(2)      ! loop about longitudes
+        ncolumn=nint(0.999*real(npart(1))*colmass(ix,jy)/ &
+             colmasstotal)
+        if (ncolumn.eq.0) goto 30
+        if (ncolumn.gt.numcolumn) numcolumn=ncolumn
 
 ! Calculate pressure at the altitudes of model surfaces, using the air density
@@ -190,14 +239,14 @@
 !*****************************************************************************
 
-      do kz=1,nz
-        pp(kz)=rho(ix,jy,kz,1)*r_air*tt(ix,jy,kz,1)
-      end do
-
-
-      deltacol=(pp(1)-pp(nz))/real(ncolumn)
-      pnew=pp(1)+deltacol/2.
-      jj=0
-      do j=1,ncolumn
-        jj=jj+1
+        do kz=1,nz
+          pp(kz)=rho(ix,jy,kz,1)*r_air*tt(ix,jy,kz,1)
+        end do
+
+
+        deltacol=(pp(1)-pp(nz))/real(ncolumn)
+        pnew=pp(1)+deltacol/2.
+        jj=0
+        do j=1,ncolumn
+          jj=jj+1
 
 
@@ -208,15 +257,15 @@
 
 
-        if (ncolumn.gt.20) then
-          pnew=pnew-deltacol
-        else
-          pnew=pp(1)-ran1(idummy)*(pp(1)-pp(nz))
-        endif
-
-        do kz=1,nz-1
-          if ((pp(kz).ge.pnew).and.(pp(kz+1).lt.pnew)) then
-            dz1=pp(kz)-pnew
-            dz2=pnew-pp(kz+1)
-            dz=1./(dz1+dz2)
+          if (ncolumn.gt.20) then
+            pnew=pnew-deltacol
+          else
+            pnew=pp(1)-ran1(idummy)*(pp(1)-pp(nz))
+          endif
+
+          do kz=1,nz-1
+            if ((pp(kz).ge.pnew).and.(pp(kz+1).lt.pnew)) then
+              dz1=pp(kz)-pnew
+              dz2=pnew-pp(kz+1)
+              dz=1./(dz1+dz2)
 
 ! Assign particle position
@@ -224,49 +273,49 @@
 ! Do the following steps only if particles are not read in from previous model run
 !*****************************************************************************
-            if (ipin.eq.0) then
-              xtra1(numpart+jj)=real(ix)-0.5+ran1(idummy)
-              if (ix.eq.0) xtra1(numpart+jj)=ran1(idummy)
-              if (ix.eq.nxmin1) xtra1(numpart+jj)= &
-                   real(nxmin1)-ran1(idummy)
-              ytra1(numpart+jj)=real(jy)-0.5+ran1(idummy)
-              ztra1(numpart+jj)=(height(kz)*dz2+height(kz+1)*dz1)*dz
-              if (ztra1(numpart+jj).gt.height(nz)-0.5) &
-                   ztra1(numpart+jj)=height(nz)-0.5
+              if (ipin.eq.0) then
+                xtra1_tmp(idx(numpart+jj))=real(ix)-0.5+ran1(idummy)
+                if (ix.eq.0) xtra1_tmp(idx(numpart+jj))=ran1(idummy)
+                if (ix.eq.nxmin1) xtra1_tmp(idx(numpart+jj))= &
+                     real(nxmin1)-ran1(idummy)
+                ytra1_tmp(idx(numpart+jj))=real(jy)-0.5+ran1(idummy)
+                ztra1_tmp(idx(numpart+jj))=(height(kz)*dz2+height(kz+1)*dz1)*dz
+                if (ztra1_tmp(idx(numpart+jj)).gt.height(nz)-0.5) &
+                     ztra1_tmp(idx(numpart+jj))=height(nz)-0.5
 
 
 ! Interpolate PV to the particle position
 !****************************************
-              ixm=int(xtra1(numpart+jj))
-              jym=int(ytra1(numpart+jj))
-              ixp=ixm+1
-              jyp=jym+1
-              ddx=xtra1(numpart+jj)-real(ixm)
-              ddy=ytra1(numpart+jj)-real(jym)
-              rddx=1.-ddx
-              rddy=1.-ddy
-              p1=rddx*rddy
-              p2=ddx*rddy
-              p3=rddx*ddy
-              p4=ddx*ddy
-              do i=2,nz
-                if (height(i).gt.ztra1(numpart+jj)) then
-                  indzm=i-1
-                  indzp=i
-                  goto 6
-                endif
-              end do
-6             continue
-              dz1=ztra1(numpart+jj)-height(indzm)
-              dz2=height(indzp)-ztra1(numpart+jj)
-              dz=1./(dz1+dz2)
-              do in=1,2
-                indzh=indzm+in-1
-                y1(in)=p1*pv(ixm,jym,indzh,1) &
-                     +p2*pv(ixp,jym,indzh,1) &
-                     +p3*pv(ixm,jyp,indzh,1) &
-                     +p4*pv(ixp,jyp,indzh,1)
-              end do
-              pvpart=(dz2*y1(1)+dz1*y1(2))*dz
-              if (ylat.lt.0.) pvpart=-1.*pvpart
+                ixm=int(xtra1_tmp(idx(numpart+jj)))
+                jym=int(ytra1_tmp(idx(numpart+jj)))
+                ixp=ixm+1
+                jyp=jym+1
+                ddx=xtra1_tmp(idx(numpart+jj))-real(ixm)
+                ddy=ytra1_tmp(idx(numpart+jj))-real(jym)
+                rddx=1.-ddx
+                rddy=1.-ddy
+                p1=rddx*rddy
+                p2=ddx*rddy
+                p3=rddx*ddy
+                p4=ddx*ddy
+                do i=2,nz
+                  if (height(i).gt.ztra1_tmp(idx(numpart+jj))) then
+                    indzm=i-1
+                    indzp=i
+                    goto 6
+                  endif
+                end do
+6               continue
+                dz1=ztra1_tmp(idx(numpart+jj))-height(indzm)
+                dz2=height(indzp)-ztra1_tmp(idx(numpart+jj))
+                dz=1./(dz1+dz2)
+                do in=1,2
+                  indzh=indzm+in-1
+                  y1(in)=p1*pv(ixm,jym,indzh,1) &
+                       +p2*pv(ixp,jym,indzh,1) &
+                       +p3*pv(ixm,jyp,indzh,1) &
+                       +p4*pv(ixp,jyp,indzh,1)
+                end do
+                pvpart=(dz2*y1(1)+dz1*y1(2))*dz
+                if (ylat.lt.0.) pvpart=-1.*pvpart
 
 
@@ -274,45 +323,46 @@
 !*****************************************************************************
 
-              if (((ztra1(numpart+jj).gt.3000.).and. &
-                   (pvpart.gt.pvcrit)).or.(mdomainfill.eq.1)) then
+                if (((ztra1_tmp(idx(numpart+jj)).gt.3000.).and. &
+                     (pvpart.gt.pvcrit)).or.(mdomainfill.eq.1)) then
 
 ! Assign certain properties to the particle
 !******************************************
-                nclass(numpart+jj)=min(int(ran1(idummy)* &
-                     real(nclassunc))+1,nclassunc)
-                numparticlecount=numparticlecount+1
-                npoint(numpart+jj)=numparticlecount
-                idt(numpart+jj)=mintime
-                itra1(numpart+jj)=0
-                itramem(numpart+jj)=0
-                itrasplit(numpart+jj)=itra1(numpart+jj)+ldirect* &
-                     itsplit
-                xmass1(numpart+jj,1)=colmass(ix,jy)/real(ncolumn)
-                if (mdomainfill.eq.2) xmass1(numpart+jj,1)= &
-                     xmass1(numpart+jj,1)*pvpart*48./29.*ozonescale/10.**9
-              else
-                jj=jj-1
+                  nclass_tmp(idx(numpart+jj))=min(int(ran1(idummy)* &
+                       real(nclassunc))+1,nclassunc)
+                  numparticlecount=numparticlecount+1
+                  npoint_tmp(idx(numpart+jj))=numparticlecount
+                  idt_tmp(idx(numpart+jj))=mintime
+                  itra1_tmp(idx(numpart+jj))=0
+                  itramem_tmp(idx(numpart+jj))=0
+                  itrasplit_tmp(idx(numpart+jj))=itra1_tmp(idx(numpart+jj))+ldirect* &
+                       itsplit
+                  xmass1_tmp(idx(numpart+jj),1)=colmass(ix,jy)/real(ncolumn)
+                  if (mdomainfill.eq.2) xmass1_tmp(idx(numpart+jj),1)= &
+                       xmass1_tmp(idx(numpart+jj),1)*pvpart*48./29.*ozonescale/10.**9
+                else
+                  jj=jj-1
+                endif
               endif
             endif
-          endif
+          end do
         end do
+        numparttot=numparttot+ncolumn
+        if (ipin.eq.0) numpart=numpart+jj
+30      continue
       end do
-      numparttot=numparttot+ncolumn
-      if (ipin.eq.0) numpart=numpart+jj
-30    continue
-    end do
-  end do
-
-
-! Check whether numpart is really smaller than maxpart per process
-!*****************************************************************
-
-  if (numpart.gt.maxpart_mpi) then
-    write(*,*) 'numpart too large: change source in init_atm_mass.f'
-    write(*,*) 'numpart: ',numpart,' maxpart: ',maxpart_mpi
-  endif
-
-
-  xmassperparticle=colmasstotal/real(numparttot)
+    end do
+
+
+! Check whether numpart is really smaller than maxpart
+!*****************************************************
+
+! ESO :TODO: this warning need to be moved further up, else out-of-bounds error earlier
+    if (numpart.gt.maxpart) then
+      write(*,*) 'numpart too large: change source in init_atm_mass.f'
+      write(*,*) 'numpart: ',numpart,' maxpart: ',maxpart
+    endif
+
+
+    xmassperparticle=colmasstotal/real(numparttot)
 
 
@@ -320,10 +370,11 @@
 !***********************************************
 
-  do j=1,numpart
-    if ((xtra1(j).lt.0.).or.(xtra1(j).ge.real(nxmin1)).or. &
-         (ytra1(j).lt.0.).or.(ytra1(j).ge.real(nymin1))) then
-      itra1(j)=-999999999
-    endif
-  end do
+!    do j=1,numpart
+    do j=1,npoint(1)
+      if ((xtra1_tmp(j).lt.0.).or.(xtra1_tmp(j).ge.real(nxmin1)).or. &
+           (ytra1_tmp(j).lt.0.).or.(ytra1_tmp(j).ge.real(nymin1))) then
+        itra1_tmp(j)=-999999999
+      endif
+    end do
 
 
@@ -340,16 +391,16 @@
 !****************************************************************************
 
-  fractus=real(numcolumn)/real(nz)
-  write(*,*) 'Total number of particles at model start: ',numpart*mp_partgroup_np
-  write(*,*) 'Maximum number of particles per column: ',numcolumn*mp_partgroup_np
-  write(*,*) 'If ',fractus*mp_partgroup_np,' <1, better use more particles'
-  fractus=sqrt(max(fractus,1.))/2.
-
-  do jy=ny_sn(1),ny_sn(2)      ! loop about latitudes
-    do ix=nx_we(1),nx_we(2)      ! loop about longitudes
-      ncolumn=nint(0.999/fractus*real(npart(1)/mp_partgroup_np)*colmass(ix,jy) &
-           /colmasstotal)
-      if (ncolumn.gt.maxcolumn) stop 'maxcolumn too small'
-      if (ncolumn.eq.0) goto 80
+    fractus=real(numcolumn)/real(nz)
+    write(*,*) 'Total number of particles at model start: ',numpart
+    write(*,*) 'Maximum number of particles per column: ',numcolumn
+    write(*,*) 'If ',fractus,' <1, better use more particles'
+    fractus=sqrt(max(fractus,1.))/2.
+
+    do jy=ny_sn(1),ny_sn(2)      ! loop about latitudes
+      do ix=nx_we(1),nx_we(2)      ! loop about longitudes
+        ncolumn=nint(0.999/fractus*real(npart(1))*colmass(ix,jy) &
+             /colmasstotal)
+        if (ncolumn.gt.maxcolumn) stop 'maxcolumn too small'
+        if (ncolumn.eq.0) goto 80
 
 
@@ -359,8 +410,8 @@
 !************************************************************************
 
-      if (ix.eq.nx_we(1)) numcolumn_we(1,jy)=ncolumn
-      if (ix.eq.nx_we(2)) numcolumn_we(2,jy)=ncolumn
-      if (jy.eq.ny_sn(1)) numcolumn_sn(1,ix)=ncolumn
-      if (jy.eq.ny_sn(2)) numcolumn_sn(2,ix)=ncolumn
+        if (ix.eq.nx_we(1)) numcolumn_we(1,jy)=ncolumn
+        if (ix.eq.nx_we(2)) numcolumn_we(2,jy)=ncolumn
+        if (jy.eq.ny_sn(1)) numcolumn_sn(1,ix)=ncolumn
+        if (jy.eq.ny_sn(2)) numcolumn_sn(2,ix)=ncolumn
 
 ! Calculate pressure at the altitudes of model surfaces, using the air density
@@ -368,22 +419,22 @@
 !*****************************************************************************
 
-      do kz=1,nz
-        pp(kz)=rho(ix,jy,kz,1)*r_air*tt(ix,jy,kz,1)
-      end do
+        do kz=1,nz
+          pp(kz)=rho(ix,jy,kz,1)*r_air*tt(ix,jy,kz,1)
+        end do
 
 ! Determine the reference starting altitudes
 !*******************************************
 
-      deltacol=(pp(1)-pp(nz))/real(ncolumn)
-      pnew=pp(1)+deltacol/2.
-      do j=1,ncolumn
-        pnew=pnew-deltacol
-        do kz=1,nz-1
-          if ((pp(kz).ge.pnew).and.(pp(kz+1).lt.pnew)) then
-            dz1=pp(kz)-pnew
-            dz2=pnew-pp(kz+1)
-            dz=1./(dz1+dz2)
-            zposition=(height(kz)*dz2+height(kz+1)*dz1)*dz
-            if (zposition.gt.height(nz)-0.5) zposition=height(nz)-0.5
+        deltacol=(pp(1)-pp(nz))/real(ncolumn)
+        pnew=pp(1)+deltacol/2.
+        do j=1,ncolumn
+          pnew=pnew-deltacol
+          do kz=1,nz-1
+            if ((pp(kz).ge.pnew).and.(pp(kz+1).lt.pnew)) then
+              dz1=pp(kz)-pnew
+              dz2=pnew-pp(kz+1)
+              dz=1./(dz1+dz2)
+              zposition=(height(kz)*dz2+height(kz+1)*dz1)*dz
+              if (zposition.gt.height(nz)-0.5) zposition=height(nz)-0.5
 
 ! Memorize vertical positions where particles are introduced
@@ -391,22 +442,22 @@
 !***********************************************************
 
-            if (ix.eq.nx_we(1)) zcolumn_we(1,jy,j)=zposition
-            if (ix.eq.nx_we(2)) zcolumn_we(2,jy,j)=zposition
-            if (jy.eq.ny_sn(1)) zcolumn_sn(1,ix,j)=zposition
-            if (jy.eq.ny_sn(2)) zcolumn_sn(2,ix,j)=zposition
+              if (ix.eq.nx_we(1)) zcolumn_we(1,jy,j)=zposition
+              if (ix.eq.nx_we(2)) zcolumn_we(2,jy,j)=zposition
+              if (jy.eq.ny_sn(1)) zcolumn_sn(1,ix,j)=zposition
+              if (jy.eq.ny_sn(2)) zcolumn_sn(2,ix,j)=zposition
 
 ! Initialize mass that has accumulated at boundary to zero
 !*********************************************************
 
-            acc_mass_we(1,jy,j)=0.
-            acc_mass_we(2,jy,j)=0.
-            acc_mass_sn(1,jy,j)=0.
-            acc_mass_sn(2,jy,j)=0.
-          endif
+              acc_mass_we(1,jy,j)=0.
+              acc_mass_we(2,jy,j)=0.
+              acc_mass_sn(1,jy,j)=0.
+              acc_mass_sn(2,jy,j)=0.
+            endif
+          end do
         end do
+80      continue
       end do
-80    continue
-    end do
-  end do
+    end do
 
 ! If particles shall be read in to continue an existing run,
@@ -415,14 +466,34 @@
 !***************************************************************************
 
-! :TODO: eso: parallelize
-  if (ipin.eq.1) then
-    open(unitboundcond,file=path(2)(1:length(2))//'boundcond.bin', &
-         form='unformatted')
-    read(unitboundcond) numcolumn_we,numcolumn_sn, &
-         zcolumn_we,zcolumn_sn,acc_mass_we,acc_mass_sn
-    close(unitboundcond)
-  endif
-
-
+! eso TODO: only needed for root process
+    if (ipin.eq.1) then
+      open(unitboundcond,file=path(2)(1:length(2))//'boundcond.bin', &
+           form='unformatted')
+      read(unitboundcond) numcolumn_we,numcolumn_sn, &
+           zcolumn_we,zcolumn_sn,acc_mass_we,acc_mass_sn
+      close(unitboundcond)
+    endif
+
+    numpart = npart(1)/mp_partgroup_np
+    if (mod(numpart,mp_partgroup_np).ne.0) numpart=numpart+1
+
+  else ! Allocate dummy arrays for receiving processes 
+    allocate(itra1_tmp(nullsize),npoint_tmp(nullsize),nclass_tmp(nullsize),&
+         & idt_tmp(nullsize),itramem_tmp(nullsize),itrasplit_tmp(nullsize),&
+         & xtra1_tmp(nullsize),ytra1_tmp(nullsize),ztra1_tmp(nullsize),&
+         & xmass1_tmp(nullsize, nullsize))
+    
+  end if ! end if(lroot)  
+
+
+! Distribute particles to other processes (numpart is 'per-process', not total)
+    call MPI_Bcast(numpart, 1, MPI_INTEGER, id_root, mp_comm_used, mp_ierr)
+! eso TODO: xmassperparticle: not necessary to send
+    call MPI_Bcast(xmassperparticle, 1, mp_sp, id_root, mp_comm_used, mp_ierr)
+    call mpif_send_part_properties(numpart)
+
+! Deallocate the temporary arrays used for all particles
+    deallocate(itra1_tmp,npoint_tmp,nclass_tmp,idt_tmp,itramem_tmp,&
+         & itrasplit_tmp,xtra1_tmp,ytra1_tmp,ztra1_tmp,xmass1_tmp)
 
 
Index: src/mean_mod.f90
===================================================================
--- src/mean_mod.f90	(revision 6a678e3fe206788e9704a724ec54e6d3dcc908e7)
+++ src/mean_mod.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -64,7 +64,7 @@
     ! real(sp),parameter :: eps=1.0e-30
 
+    integer,intent(in) :: number
     real(sp), intent(in) :: x_sp(number)
     real(sp), intent(out) ::xm,xs
-    integer,intent(in) :: number
     real(sp) :: xl,xq,xaux
     real(sp),parameter :: eps=1.0e-30
@@ -116,7 +116,7 @@
     implicit none
 
+    integer,intent(in) :: number
     real(dp), intent(in) :: x_dp(number)
     real(dp), intent(out) ::xm,xs
-    integer,intent(in) :: number
     real(dp) :: xl,xq,xaux
     real(dp),parameter :: eps=1.0e-30
@@ -168,7 +168,7 @@
     implicit none
 
+    integer,intent(in) :: number
     real(dp), intent(in) :: x_dp(number)
     real(sp), intent(out) ::xm,xs
-    integer,intent(in) :: number
     real(sp) :: xl,xq,xaux
     real(sp),parameter :: eps=1.0e-30
Index: src/mpi_mod.f90
===================================================================
--- src/mpi_mod.f90	(revision 861805ae954eff7a3f8d5a66162fa14555f6e59e)
+++ src/mpi_mod.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -122,5 +122,5 @@
   logical, parameter :: mp_dev_mode = .false.
   logical, parameter :: mp_dbg_out = .false.
-  logical, parameter :: mp_time_barrier=.false.
+  logical, parameter :: mp_time_barrier=.true.
   logical, parameter :: mp_measure_time=.false.
   logical, parameter :: mp_exact_numpart=.true.
@@ -251,5 +251,5 @@
         write(*,FMT='(80("#"))')
       end if
-      lmp_sync=.true. ! :DBG: eso fix this...
+      lmp_sync=.true.
     end if
 
@@ -261,4 +261,5 @@
 !**********************************************************************
 
+!    id_read = min(mp_np-1, 1)
     id_read = mp_np-1
 
@@ -486,4 +487,17 @@
     integer :: i,jj, addone
 
+! Exit if too many particles
+    if (num_part.gt.maxpart_mpi) then
+      write(*,*) '#####################################################'
+      write(*,*) '#### ERROR - TOTAL NUMBER OF PARTICLES REQUIRED  ####'
+      write(*,*) '#### EXCEEDS THE MAXIMUM ALLOWED NUMBER. REDUCE  ####'
+      write(*,*) '#### EITHER NUMBER OF PARTICLES PER RELEASE POINT####'
+      write(*,*) '#### OR INCREASE MAXPART.                        ####'
+      write(*,*) '#####################################################'
+!      call MPI_FINALIZE(mp_ierr)
+      stop
+    end if
+
+
 ! Time for MPI communications
 !****************************
@@ -527,5 +541,4 @@
 
     if (mp_measure_time) call mpif_mtime('commtime',1)
-    write(*,*) "PID ", mp_partid, "ending MPI_Scatter operation"
 
     goto 601
@@ -535,5 +548,5 @@
 
 ! After the transfer of particles it it possible that the value of
-! "numpart" is larger than the actual, so we reduce it if there are
+! "numpart" is larger than the actual used, so we reduce it if there are
 ! invalid particles at the end of the arrays
 601 do i=num_part, 1, -1
@@ -628,4 +641,8 @@
         if ( numparticles_mpi(idx_arr(m)).gt.mp_min_redist.and.&
              & real(num_trans)/real(numparticles_mpi(idx_arr(m))).gt.mp_redist_fract) then
+! DBG
+          ! write(*,*) 'mp_partid, idx_arr(m), idx_arr(i), mp_min_redist, num_trans, numparticles_mpi', &
+          !      &mp_partid, idx_arr(m), idx_arr(i), mp_min_redist, num_trans, numparticles_mpi
+! DBG
           call mpif_redist_part(itime, idx_arr(m), idx_arr(i), num_trans/2)
         end if
@@ -661,4 +678,12 @@
     integer :: i, j, minpart, ipart, maxnumpart
  
+! Check for invalid input arguments
+!**********************************
+ if (src_proc.eq.dest_proc) then
+   write(*,*) '<mpi_mod::mpif_redist_part>: Error: &
+        &src_proc.eq.dest_proc' 
+   stop
+ end if
+
 ! Measure time for MPI communications
 !************************************
@@ -674,9 +699,9 @@
       ul=numpart
 
-      ! if (mp_dev_mode) then
-      !   write(*,FMT='(72("#"))')
-      !   write(*,*) "Sending ", num_trans, "particles (from/to)", src_proc, dest_proc
-      !   write(*,*) "numpart before: ", numpart
-      ! end if
+      if (mp_dev_mode) then
+        write(*,FMT='(72("#"))')
+        write(*,*) "Sending ", num_trans, "particles (from/to)", src_proc, dest_proc
+        write(*,*) "numpart before: ", numpart
+      end if
 
       call MPI_SEND(nclass(ll:ul),num_trans,&
@@ -717,8 +742,8 @@
       numpart = numpart-num_trans
 
-      ! if (mp_dev_mode) then
-      !   write(*,*) "numpart after: ", numpart
-      !   write(*,FMT='(72("#"))')
-      ! end if
+      if (mp_dev_mode) then
+        write(*,*) "numpart after: ", numpart
+        write(*,FMT='(72("#"))')
+      end if
 
     else if (mp_partid.eq.dest_proc) then
@@ -731,9 +756,9 @@
       ul=numpart+num_trans
 
-      ! if (mp_dev_mode) then
-      !   write(*,FMT='(72("#"))')
-      !   write(*,*) "Receiving ", num_trans, "particles (from/to)", src_proc, dest_proc
-      !   write(*,*) "numpart before: ", numpart
-      ! end if
+      if (mp_dev_mode) then
+        write(*,FMT='(72("#"))')
+        write(*,*) "Receiving ", num_trans, "particles (from/to)", src_proc, dest_proc
+        write(*,*) "numpart before: ", numpart
+      end if
 
 ! We could receive the data directly at nclass(ll:ul) etc., but this leaves
@@ -785,32 +810,33 @@
       do i=1, num_trans
 ! Take into acount that we may have transferred invalid particles
-        if (itra1_tmp(minpart).ne.itime) goto 200
+        if (itra1_tmp(i).ne.itime) cycle
         do ipart=minpart,maxnumpart
           if (itra1(ipart).ne.itime) then
-            itra1(ipart) = itra1_tmp(minpart)
-            npoint(ipart) = npoint_tmp(minpart)
-            nclass(ipart) = nclass_tmp(minpart)
-            idt(ipart) = idt_tmp(minpart)
-            itramem(ipart) = itramem_tmp(minpart)
-            itrasplit(ipart) = itrasplit_tmp(minpart)
-            xtra1(ipart) = xtra1_tmp(minpart)
-            ytra1(ipart) = ytra1_tmp(minpart)
-            ztra1(ipart) = ztra1_tmp(minpart)
-            xmass1(ipart,:) = xmass1_tmp(minpart,:)
-! Increase numpart, if necessary
-            numpart=max(numpart,ipart)
+            itra1(ipart) = itra1_tmp(i)
+            npoint(ipart) = npoint_tmp(i)
+            nclass(ipart) = nclass_tmp(i)
+            idt(ipart) = idt_tmp(i)
+            itramem(ipart) = itramem_tmp(i)
+            itrasplit(ipart) = itrasplit_tmp(i)
+            xtra1(ipart) = xtra1_tmp(i)
+            ytra1(ipart) = ytra1_tmp(i)
+            ztra1(ipart) = ztra1_tmp(i)
+            xmass1(ipart,:) = xmass1_tmp(i,:)
             goto 200 ! Storage space has been found, stop searching
           end if
+! :TODO: add check for if too many particles requiried
         end do
-200     minpart=minpart+1
+200     minpart=ipart+1
       end do
+! Increase numpart, if necessary
+      numpart=max(numpart,ipart)
 
       deallocate(itra1_tmp,npoint_tmp,nclass_tmp,idt_tmp,itramem_tmp,itrasplit_tmp,&
            & xtra1_tmp,ytra1_tmp,ztra1_tmp,xmass1_tmp)
 
-      ! if (mp_dev_mode) then
-      !   write(*,*) "numpart after: ", numpart
-      !   write(*,FMT='(72("#"))')
-      ! end if
+      if (mp_dev_mode) then
+        write(*,*) "numpart after: ", numpart
+        write(*,FMT='(72("#"))')
+      end if
 
     else
@@ -2727,6 +2753,7 @@
 ! write(*,FMT='(A60,TR1,F9.2)') 'TOTAL CPU TIME FOR VERTTRANSFORM:',&
 !      & mp_vt_time_total
-! NB: the 'flush' function is possibly a gfortran-specific extension
-          call flush()
+! NB: the 'flush' function is possibly a gfortran-specific extension,
+! comment out if it gives problems
+!          call flush()
         end if
       end do
Index: src/releaseparticles_mpi.f90
===================================================================
--- src/releaseparticles_mpi.f90	(revision 861805ae954eff7a3f8d5a66162fa14555f6e59e)
+++ src/releaseparticles_mpi.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -416,5 +416,4 @@
           endif
         end do
-! ESO TODO: Here we could use dynamic allocation and increase array sizes
         if (ipart.gt.maxpart_mpi) goto 996
 
Index: src/timemanager_mpi.f90
===================================================================
--- src/timemanager_mpi.f90	(revision 861805ae954eff7a3f8d5a66162fa14555f6e59e)
+++ src/timemanager_mpi.f90	(revision 16b61a5e2d3b1020be1cff080e479ba26f3f7063)
@@ -578,5 +578,5 @@
         end if
 
-        ! Write particles for all processes
+        ! Write number of particles for all processes
         if (mp_dev_mode) write(*,*) "PID, itime, numpart", mp_pid,itime,numpart
 
@@ -870,5 +870,6 @@
   endif
   deallocate(gridunc)
-  deallocate(xpoint1,xpoint2,ypoint1,ypoint2,zpoint1,zpoint2,xmass, checklifetime)
+  deallocate(xpoint1,xpoint2,ypoint1,ypoint2,zpoint1,zpoint2,xmass)
+  if (allocated(checklifetime)) deallocate(checklifetime)
   deallocate(ireleasestart,ireleaseend,npart,kindz)
   deallocate(xmasssave)
