subroutine denspot_full_density(denspot, rho_full, iproc, new)
  use module_precisions
  use module_bigdft_mpi
  use module_bigdft_arrays
  use module_types
  use memory_profiling
  implicit none
  type(DFT_local_fields), intent(in) :: denspot
  integer, intent(in) :: iproc
  integer, intent(out) :: new
  real(gp), dimension(:), pointer :: rho_full

  character(len = *), parameter :: subname = "denspot_full_density"
  integer :: nslice, ierr, irhodim, irhoxcsh

  new = 0
  nslice = max(denspot%dpbox%ndimpot, 1)
  if (nslice < denspot%dpbox%mesh%ndim) then
     if (iproc == 0) then
        !allocate full density in pot_ion array
        rho_full = f_malloc_ptr(denspot%dpbox%mesh%ndim*denspot%dpbox%nrhodim,id='rho_full')
        new = 1

        ! Ask to gather density to other procs.
        !LG: wtf is that? call MPI_BCAST(0, 1, MPI_INTEGER, 0, bigdft_mpi%mpi_comm, ierr)
     end if

     if (denspot%dpbox%ndimrhopot > 0) then
        irhoxcsh = nslice / denspot%dpbox%n3p * denspot%dpbox%i3xcsh
     else
        irhoxcsh = 0
     end if
     do irhodim = 1, denspot%dpbox%nrhodim, 1
        if (iproc == 0) then
           call MPI_GATHERV(denspot%rhov(nslice * (irhodim - 1) + irhoxcsh + 1),&
                nslice,mpidtypd,rho_full(denspot%dpbox%mesh%ndim * (irhodim - 1) + 1),&
                denspot%dpbox%ngatherarr(0,1),denspot%dpbox%ngatherarr(0,2),&
                mpidtypd,0,bigdft_mpi%mpi_comm,ierr)
        else
           call MPI_GATHERV(denspot%rhov(nslice * (irhodim - 1) + irhoxcsh + 1),&
                nslice,mpidtypd,rho_full(1),&
                denspot%dpbox%ngatherarr(0,1),denspot%dpbox%ngatherarr(0,2),&
                mpidtypd,0,bigdft_mpi%mpi_comm,ierr)
        end if
     end do
  else
     rho_full => denspot%rhov
  end if
END SUBROUTINE denspot_full_density


subroutine denspot_full_v_ext(denspot, pot_full, iproc, new)
  use module_precisions
  use module_bigdft_mpi
  use module_types
  use memory_profiling
  implicit none
  type(DFT_local_fields), intent(in) :: denspot
  integer, intent(in) :: iproc
  integer, intent(out) :: new
  real(gp), pointer :: pot_full(:)

  character(len = *), parameter :: subname = "localfields_full_potential"
  integer :: ierr

  new = 0
  if (denspot%dpbox%ndimpot < denspot%dpbox%mesh%ndim) then
     if (iproc == 0) then
        !allocate full density in pot_ion array
        pot_full = f_malloc_ptr(denspot%dpbox%mesh%ndim,id='pot_full')
        new = 1

        ! Ask to gather density to other procs.
        !!!call MPI_BCAST(1, 1, MPI_INTEGER, 0, bigdft_mpi%mpi_comm, ierr)
     end if

     call MPI_GATHERV(denspot%v_ext(1,1,1,1),max(denspot%dpbox%ndimpot, 1),&
          mpidtypd,pot_full(1),denspot%dpbox%ngatherarr(0,1),&
          denspot%dpbox%ngatherarr(0,2),mpidtypd,0,bigdft_mpi%mpi_comm,ierr)
  else
     pot_full => denspot%rhov
  end if
END SUBROUTINE denspot_full_v_ext


subroutine denspot_emit_rhov(denspot, iter, iproc, nproc)
  use module_precisions
  use module_bigdft_mpi
  use module_bigdft_profiling
  use module_bigdft_arrays
  use module_types
  implicit none
  type(DFT_local_fields), intent(in) :: denspot
  integer, intent(in) :: iter, iproc, nproc

  character(len = *), parameter :: subname = "denspot_emit_rhov"
  integer, parameter :: SIGNAL_DONE = -1
  integer, parameter :: SIGNAL_DENSITY = 0
  integer :: message, new
  real(gp), pointer :: full_dummy(:)
  interface
     subroutine denspot_full_density(denspot, rho_full, iproc, new)
       use module_precisions
       use module_types
       implicit none
       type(DFT_local_fields), intent(in) :: denspot
       integer, intent(in) :: iproc
       integer, intent(out) :: new

       real(gp), dimension(:), pointer :: rho_full
     END SUBROUTINE denspot_full_density
  end interface

  call timing(iproc,'rhov_signals  ','ON')
  if (iproc == 0) then
     ! Only iproc 0 emit the signal. This call is blocking.
     ! All other procs are blocked by the bcast to wait for
     ! possible transfer to proc 0.
     call localfields_emit_rhov(denspot%c_obj, iter)
     if (nproc > 1) then
        ! After handling the signal, iproc 0 broadcasts to other
        ! proc to continue (jproc == -1).
        message = SIGNAL_DONE
        call fmpi_bcast(message, 1,comm=bigdft_mpi%mpi_comm)
     end if
  else
     do
        call fmpi_bcast(message, 1,comm=bigdft_mpi%mpi_comm)
        if (message == SIGNAL_DONE) then
           exit
        else if (message == SIGNAL_DENSITY) then
           full_dummy = f_malloc_ptr(denspot%dpbox%nrhodim,id='full_dummy')
           ! Gather density to iproc 0
           call denspot_full_density(denspot, full_dummy, iproc, new)
           call f_free_ptr(full_dummy)
        end if
     end do
  end if
  call timing(iproc,'rhov_signals  ','OF')
END SUBROUTINE denspot_emit_rhov

subroutine denspot_emit_v_ext(denspot, iproc, nproc)
  use module_precisions
  use module_bigdft_mpi
  use module_bigdft_profiling
  use module_bigdft_arrays
  use module_types
  implicit none
  !Arguments
  type(DFT_local_fields), intent(in) :: denspot
  integer, intent(in) :: iproc, nproc
  !Local variables
  character(len = *), parameter :: subname = "denspot_emit_v_ext"
  integer, parameter :: SIGNAL_DONE = -1
  integer :: message, new
  !integer :: ierr
  real(gp), pointer :: full_dummy(:)
  interface
     subroutine denspot_full_v_ext(denspot, pot_full, iproc, new)
       use module_precisions
       use module_types
       implicit none
       type(DFT_local_fields), intent(in) :: denspot
       integer, intent(in) :: iproc
       integer, intent(out) :: new
       real(gp), pointer :: pot_full(:)
     END SUBROUTINE denspot_full_v_ext
  end interface

  call timing(iproc,'rhov_signals  ','ON')
  if (iproc == 0) then
     ! Only iproc 0 emit the signal. This call is blocking.
     ! All other procs are blocked by the bcast to wait for
     ! possible transfer to proc 0.
     call localfields_emit_v_ext(denspot%c_obj)
     if (nproc > 1) then
        ! After handling the signal, iproc 0 broadcasts to other
        ! proc to continue (jproc == -1).
        message = SIGNAL_DONE
        call fmpi_bcast(message, 1,comm=bigdft_mpi%mpi_comm)
     end if
  else
     do
        call fmpi_bcast(message, 1,comm=bigdft_mpi%mpi_comm)
        !call MPI_BCAST(message, 1, MPI_INTEGER, 0, bigdft_mpi%mpi_comm, ierr)
        if (message == SIGNAL_DONE) then
           exit
        else
           full_dummy = f_malloc_ptr(1,id='full_dummy')
           ! Gather density to iproc 0
           call denspot_full_v_ext(denspot, full_dummy, iproc, new)
           call f_free_ptr(full_dummy)
        end if
     end do
  end if
  call timing(iproc,'rhov_signals  ','OF')
END SUBROUTINE denspot_emit_v_ext
