! this source file contains subroutines that return information about
! nubeam's beam and fusion product fast ion distribution functions.

! these routines can be called after a nubeam time step has been completed
! (or at least, after an nbstart call).

! to find species indices (iindx arguments) see integer function index_nbfi
! in nbfi_lbl.f90

subroutine nbi_fbm_nzons_e(iindx,nume)

  !  number of energy zones, by species

  use nbi_com
  implicit none

  integer, intent(in) :: iindx  ! specie index
  integer, intent(out) :: nume  ! number of energy zones

  !----------------

  if((iindx.le.0).or.(iindx.gt.mibs)) then
     write(nonlin,*) ' ?nbi_fbm_nzons_e: specie index not in range: ',iindx
     write(nonlin,*) '  expected range: between 1 and ',mibs,'.'
     nume = 0
  else
     nume = nznbmea(iindx)
  endif

end subroutine nbi_fbm_nzons_e

subroutine nbi_fbm_nzons_vpv(iarg,numa)

  !  number of pitch zones.  at present all species have the same number,
  !  and, "iarg" is a dummy, placeholder argument.

  use nbi_com
  implicit none

  integer, intent(in) :: iarg   ! (dummy) specie index
  integer, intent(out) :: numa  ! number of vpll/v zones

  !----------------

  if((iarg.le.0).or.(iarg.gt.mibs)) then
     numa = nznbma
  else
     numa = nznbma
  endif

end subroutine nbi_fbm_nzons_vpv

subroutine nbi_fbm_vpvzons(iarg,isize,vpv_out,ierr)

  !  return array of vpll/v values at pitch zone centers.
  !  (nznbma) values are returned; array size (isize) must be sufficient
  !  to accomodate this

  !  at present all species have the same number,
  !  "iarg" is a dummy, placeholder argument.

  use nbi_com
  implicit none

  integer, intent(in) :: iarg   ! (dummy) specie index
  integer, intent(in) :: isize  ! size of output array

  real(fp), intent(out) :: vpv_out(isize)  ! vpll/v grid values at zone centers
  integer, intent(out) :: ierr  ! return code: 0=ok; 1 means: isize too small

  integer :: ii
  !-----------------------------

  ierr = 0

  if(isize.lt.nznbma) then
     write(nonlin,*) ' ?nbi_fbm_vpvzons: "vpv_out" array size too small.'
     write(nonlin,*) '  passed size = ',isize,'; minimum required size = ', &
          nznbma
     vpv_out = zero
     ierr = 1
  else
     if(isize.gt.nznbma) vpv_out(nznbma+1:isize) = zero
     do ii=1,nznbma
        vpv_out(ii) = -one + (ii-half)*two/(nznbma)
     enddo
  endif

end subroutine nbi_fbm_vpvzons

subroutine nbi_fbm_vpvbdys(iarg,isize,vpv_out,ierr)

  !  return array of vpll/v values at pitch zone boundaries
  !  (nznbma+1) values are returned; array size (isize) must be sufficient
  !  to accomodate this

  !  at present all species have the same number,
  !  "iarg" is a dummy, placeholder argument.

  use nbi_com
  implicit none

  integer, intent(in) :: iarg   ! (dummy) specie index
  integer, intent(in) :: isize  ! size of output array

  real(fp), intent(out) :: vpv_out(isize)  ! vpll/v grid values at zone bdys
  integer, intent(out) :: ierr  ! return code: 0=ok; 1 means: isize too small
  integer :: ii
  !-----------------------------

  ierr = 0

  if(isize.lt.(nznbma+1)) then
     write(nonlin,*) ' ?nbi_fbm_vpvbdys: "vpv_out" array size too small.'
     write(nonlin,*) '  passed size = ',isize,'; minimum required size = ', &
          nznbma + 1
     vpv_out = zero
     ierr = 1
  else
     if(isize.gt.nznbma+1) vpv_out(nznbma+2:isize) = zero
     vpv_out(1) = -one
     do ii=2,nznbma
        vpv_out(ii) = -one + (ii-one)*two/(nznbma)
     enddo
     vpv_out(nznbma+1) = one
  endif

end subroutine nbi_fbm_vpvbdys

subroutine nbi_fbm_ezons(iindx,isize,e_out,ierr)

  !  return array of energy values at energy grid zone centers.
  !  (nznbmea(iindx)) values are returned; array size (isize) must be 
  !  sufficient to accomodate this

  !  => energies in ev 

  use nbi_com
  implicit none

  integer, intent(in) :: iindx  ! specie index
  integer, intent(in) :: isize  ! size of output array

  real(fp), intent(out) :: e_out(isize)  ! energy grid values at zone centers: ev
  integer, intent(out) :: ierr  ! return code: 0=ok
  integer :: ii,inum
  !-----------------------------

  ierr = 0

  if((iindx.le.0).or.(iindx.gt.mibs)) then
     write(nonlin,*) ' ?nbi_fbm_ezons: specie index not in range: ',iindx
     write(nonlin,*) '  expected range: between 1 and ',mibs,'.'
     e_out = zero
     ierr = 1
     return
  endif

  inum = nznbmea(iindx)

  if(isize.lt.inum) then
     write(nonlin,*) ' ?nbi_fbm_ezons: "e_out" array size too small.'
     write(nonlin,*) '  passed size = ',isize,'; minimum required size = ', &
          inum
     e_out = zero
     ierr = 2
  else
     if(isize.gt.inum) e_out(inum+1:isize) = zero
     e_out(1:inum) = efbm(1:inum,iindx)
  endif

end subroutine nbi_fbm_ezons

subroutine nbi_fbm_ebdys(iindx,isize,e_out,ierr)

  !  return array of energy values at energy grid zone boundaries.
  !  (nznbmea(iindx)+1) values are returned; array size (isize) must be 
  !  sufficient to accomodate this

  !  => energies in ev 

  use nbi_com
  implicit none

  integer, intent(in) :: iindx  ! specie index
  integer, intent(in) :: isize  ! size of output array

  real(fp), intent(out) :: e_out(isize)  ! energy grid values at zone bdys: ev
  integer, intent(out) :: ierr  ! return code: 0=ok

  integer :: ii,inum
  !-----------------------------

  ierr = 0

  if((iindx.le.0).or.(iindx.gt.mibs)) then
     write(nonlin,*) ' ?nbi_fbm_ebdys: specie index not in range: ',iindx
     write(nonlin,*) '  expected range: between 1 and ',mibs,'.'
     e_out = zero
     ierr = 1
     return
  endif

  inum = nznbmea(iindx) + 1

  if(isize.lt.inum) then
     write(nonlin,*) ' ?nbi_fbm_vpvbdys: "e_out" array size too small.'
     write(nonlin,*) '  passed size = ',isize,'; minimum required size = ', &
          inum
     e_out = zero
     ierr = 2
  else
     if(isize.gt.inum) e_out(inum+1:isize) = zero
     e_out(1:inum) = efbmb(1:inum,iindx)
  endif

end subroutine nbi_fbm_ebdys
