Index: codes/icosagcm/trunk/src/parallel/domain.f90
===================================================================
--- codes/icosagcm/trunk/src/parallel/domain.f90	(revision 880)
+++ codes/icosagcm/trunk/src/parallel/domain.f90	(revision 881)
@@ -242,4 +242,6 @@
   SUBROUTINE assign_cell
   USE metric
+  USE mpipara
+  USE ioipsl
   IMPLICIT NONE
     INTEGER :: ind_d,ind,ind2,e,v
@@ -248,6 +250,28 @@
     TYPE(t_domain),POINTER :: d
     INTEGER :: delta
-     
-    
+    INTEGER :: nbp, nn, M
+    REAL :: rn
+    INTEGER, ALLOCATABLE :: nb_own(:)
+    INTEGER :: mean_own, side
+
+    ALLOCATE(nb_own(0:ndomain_glo))
+    nb_own(:)=0
+
+    DO ind_d=1,ndomain_glo
+      d=>domain_glo(ind_d)
+      nf=d%face
+      DO j=d%jj_begin,d%jj_end
+        DO i=d%ii_begin,d%ii_end
+          ii=d%ii_begin_glo-d%ii_begin+i
+          jj=d%jj_begin_glo-d%jj_begin+j
+          ind=vertex_glo(ii,jj,nf)%ind
+          cell_glo(ind)%assign_domain=0
+        ENDDO
+      ENDDO
+    ENDDO
+        
+
+
+    nbp=0
     DO ind_d=1,ndomain_glo
       d=>domain_glo(ind_d)
@@ -260,8 +284,11 @@
           delta=vertex_glo(ii,jj,nf)%delta
           IF (cell_glo(ind)%assign_face==nf) THEN 
+            nb_own(cell_glo(ind)%assign_domain)=nb_own(cell_glo(ind)%assign_domain)-1
+            nb_own(ind_d)=nb_own(ind_d)+1
             cell_glo(ind)%assign_domain=ind_d
             cell_glo(ind)%assign_i=i
             cell_glo(ind)%assign_j=j
           ENDIF
+
           IF ( i+1 <= d%ii_end ) CALL assign_edge(ind_d,ind,i,j,delta,0)
           IF ( j+1 <= d%jj_end ) CALL assign_edge(ind_d,ind,i,j,delta,1)
@@ -277,7 +304,66 @@
           IF ( i+1 <= d%ii_end .AND.  j-1 >= d%jj_begin)  CALL assign_vertex(ind_d,ind,i,j,delta,4)
           IF ( i+1 <= d%ii_end .AND.  j-1 >= d%jj_begin)  CALL assign_vertex(ind_d,ind,i,j,delta,5)
+          
+          IF (j==d%jj_begin .OR. j==d%jj_begin .OR. i==d%ii_begin .OR. i==d%ii_end) nbp=nbp+1
+ 
         ENDDO
       ENDDO
     ENDDO
+
+
+! dynamic load balancing for owned cells. Get ownership of a cell if local cells number < mean cell number
+! use random shot on frontier
+
+    mean_own=sum(nb_own(1:ndomain_glo))/ndomain_glo
+    IF (is_mpi_master) PRINT*,"Before balance : Mean own ", sum(nb_own(1:ndomain_glo))/ndomain_glo, "Min own", minval(nb_own(1:ndomain_glo)), "Max own", maxval(nb_own(1:ndomain_glo))
+! set random seed to get reproductibility when using a different number of process
+
+    CALL RANDOM_SEED(size=M)
+    CALL RANDOM_SEED(put=(/(i,i=1,M)/))
+   
+    DO nn=1,1000*nbp
+   
+      CALL random_number(rn)
+      ind_d = INT(ndomain_glo*rn)+1
+      IF (nb_own(ind_d) >= mean_own) CYCLE
+      
+      d=>domain_glo(ind_d)
+      nf=d%face
+      
+      CALL random_number(rn)
+      side=INT(4*rn)
+      IF (side==0) THEN
+        CALL random_number(rn)
+        i = INT((d%ii_end-d%ii_begin+1)*rn)+d%ii_begin
+        j = d%jj_begin
+      ELSE IF (side==1) THEN
+        CALL random_number(rn)
+        i = INT((d%ii_end-d%ii_begin+1)*rn)+d%ii_begin
+        j = d%jj_end
+      ELSE IF (side==2) THEN
+        CALL random_number(rn)
+        j = INT((d%jj_end-d%jj_begin+1)*rn)+d%jj_begin
+        i = d%ii_begin
+      ELSE IF (side==3) THEN
+        CALL random_number(rn)
+        j = INT((d%jj_end-d%jj_begin+1)*rn)+d%jj_begin
+        i = d%ii_end
+      ENDIF
+
+      ii=d%ii_begin_glo-d%ii_begin+i
+      jj=d%jj_begin_glo-d%jj_begin+j
+      ind=vertex_glo(ii,jj,nf)%ind
+      delta=vertex_glo(ii,jj,nf)%delta
+      IF (cell_glo(ind)%assign_face==nf) THEN 
+         nb_own(cell_glo(ind)%assign_domain)=nb_own(cell_glo(ind)%assign_domain)-1
+         nb_own(ind_d)=nb_own(ind_d)+1
+         cell_glo(ind)%assign_domain=ind_d
+         cell_glo(ind)%assign_i=i
+         cell_glo(ind)%assign_j=j
+      ENDIF
+   
+    ENDDO
+
+    IF (is_mpi_master) PRINT*,"After balance :Mean own ", sum(nb_own(1:ndomain_glo))/ndomain_glo, "Min own", minval(nb_own(1:ndomain_glo)), "Max own", maxval(nb_own(1:ndomain_glo))
     
     
