reallocate blocks into processors for load balance
subroutine load_balance use mod_forest use mod_global_parameters use mod_space_filling_curve use mod_amr_solution_node, only: getnode,putnode use mod_functions_forest, only: change_ipe_tree_leaf integer :: Morton_no, ipe !> MPI recv send variables for staggered-variable AMR integer :: itag_stg integer, dimension(:,:), allocatable :: recvstatus_stg, sendstatus_stg ! Jannis: for now, not using version for passive/active blocks call get_Morton_range() if (npe==1) then sfc_to_igrid(:)=sfc(1,Morton_start(mype):Morton_stop(mype)) return end if irecv=0 isend=0 n_lb_snd=0 n_lb_rcv=0 if (.not.allocated(recvrequest)) then allocate(recvstatus(MPI_STATUS_SIZE,npe),recvrequest(npe),& sendstatus(MPI_STATUS_SIZE,npe),sendrequest(npe)) allocate(lb_send_pe(npe),lb_send_pe_off(npe),lb_send_pe_len(npe),& lb_recv_pe(npe),lb_recv_pe_off(npe),lb_recv_pe_len(npe)) end if recvrequest=MPI_REQUEST_NULL sendrequest=MPI_REQUEST_NULL if(stagger_grid) then allocate(recvstatus_stg(MPI_STATUS_SIZE,max_blocks*3),& recvrequest_stg(max_blocks*3), sendstatus_stg(MPI_STATUS_SIZE,& max_blocks*3),sendrequest_stg(max_blocks*3)) recvrequest_stg=MPI_REQUEST_NULL sendrequest_stg=MPI_REQUEST_NULL end if ! Only the descriptors are allocated up front, and they are integers. The ! data buffers are sized by what actually migrates, in ! exchange_migrated_blocks, once the walk below has counted it. if ( .not. allocated(lb_snd_igrid) ) then allocate( lb_snd_igrid(max_blocks), lb_snd_ibuf(max_blocks), & lb_snd_dest(max_blocks), lb_snd_key(max_blocks), & lb_rcv_igrid(max_blocks), lb_rcv_ibuf(max_blocks), & lb_rcv_src(max_blocks), lb_rcv_key(max_blocks) ) end if do ipe=0,npe-1; do Morton_no=Morton_start(ipe),Morton_stop(ipe) recv_ipe=ipe send_igrid=sfc(1,Morton_no) send_ipe=sfc(2,Morton_no) if (recv_ipe/=send_ipe) then ! get an igrid number for the new node in recv_ipe processor recv_igrid=getnode(recv_ipe) ! update node igrid and ipe on the tree call change_ipe_tree_leaf(recv_igrid,recv_ipe,send_igrid,send_ipe) ! receive physical data of the new node in recv_ipe processor if (recv_ipe==mype) call lb_recv ! send physical data of the old node in send_ipe processor if (send_ipe==mype) call lb_send end if if (recv_ipe==mype) then if (recv_ipe==send_ipe) then sfc_to_igrid(Morton_no)=send_igrid else sfc_to_igrid(Morton_no)=recv_igrid end if end if end do; end do ! Lay the blocks out per peer, exchange them in one message each, and apply ! them. The walk above only recorded descriptors. call exchange_migrated_blocks ! The staggered path still posts per block; see the note in lb_send. It is ! unreachable here (stagger_grid is false and fix_edges is not called), so ! it is left as it was found. if(stagger_grid) then if (irecv>0) call MPI_WAITALL(irecv,recvrequest_stg,recvstatus_stg,& ierrmpi) if (isend>0) call MPI_WAITALL(isend,sendrequest_stg,sendstatus_stg,& ierrmpi) end if if(stagger_grid) deallocate(recvstatus_stg,recvrequest_stg,sendstatus_stg,& sendrequest_stg) ! post processing do ipe=0,npe-1; do Morton_no=Morton_start(ipe),Morton_stop(ipe) recv_ipe=ipe send_igrid=sfc(1,Morton_no) send_ipe=sfc(2,Morton_no) if (recv_ipe/=send_ipe) then !if (send_ipe==mype) call dealloc_node(send_igrid) call putnode(send_igrid,send_ipe) end if end do; end do ! Update sfc array: igrid and ipe info in space filling curve call amr_Morton_order() end subroutine load_balance