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)
 
 
