subroutine hatom_btsigv(irtype,beamchrg,eabeam,tatarg,n,izbeam,iztarg, &
     btsigv, istat )
 
  use hatom_mod
 
  implicit NONE
 
  !  get maxwellian averaged beam-target <sigma*v> for a charge exchange
  !  or impact ionization reaction between light neutral atoms and light
  !  fully stripped ions [H,HE,LI]x[H+,HE++,LI+++]
  !    ---caution-- as of June 2001, the atomic physics database does
  !                 not have all good data on LI.
  !
  !  this routine can also be used to retrieve <Eav> = average energy,
  !    KeV, of the cx reagent sampled out of the maxwellian target of
  !    a beam-target cx reaction; <Eav> can be used to refine the
  !    calculation of the charge exchange driven power exchange between
  !    the beam and target populations.
  !
  !  this routine can also be used to retrieve the dimensionless
  !
  !    <fd> = < vb.vtarg / (|vb|*|vth|) >
  !
  !  which tells whether the average cx reagent sampled has a velocity
  !  component parallel to (<fd> .gt. 0) or anti-parallel to (<fd> .lt. 0)
  !  the direction of the beam; note vth = sqrt(Ti/mi) of the target
  !  Maxwellian; <fd> can be used to refine the calculation of the
  !  charge exchange driven momentum exchange between the beam and
  !  target populations.
  !
  !  here, "charge exchange" refers to an ion-neutral reaction, in which
  !  charges are exchanged ***and the ion is neutralized***; a reaction
  !  in which an electron is exchanged but the receiving particle is
  !  not neutralized, should be counted as an impact ionization event.
  !  The rationale:  this routine is intended for use in modeling of
  !  high temperature plasmas; a partially stripped light impurity is
  !  quickly fully stripped, so that the net result of a partial
  !  charge exchange reaction is two fully stripped ions, same as
  !  a "pure" impact ionization reaction.
  !
  !  a result of ZERO is returned if there is no neutralizing
  !  charge exchange reaction (e.g He++ cannot be neutralized by cx
  !  with an H neutral beam)
  !
  !  a result of ERROR (-1) is returned if invalid arguments
  !  are passed.
 
  integer, parameter :: CX=1, II=2, EAV=3, FD=4
 
  integer, parameter :: NEUTRAL=1, ION=2
 
  integer, parameter :: H=1, HE=2, LI=3
 
  real*8, parameter :: ZERO=0.0d0, ERROR=-1.0D0
  integer, parameter :: IZERO=-1, IERROR=-2
 
  !--------------------------------------------
  !  **subroutine arguments**
 
  integer, intent(in) :: irtype   ! reaction type: =cx or =ii or =eav or =fd
  integer, intent(in) :: beamchrg ! beam type: =neutral or =ion
 
  ! if the beam is neutral, the target maxwellian contains ions
  ! if it is an ion beam, the target maxwellian contains neutrals
 
  integer, intent(in) :: n        ! **vector size**
  real*8, intent(in) :: eabeam(n)    ! E/A, KeV/nucleon, of beam   **vector**
  real*8, intent(in) :: tatarg(n)    ! T/A, KeV/nucleon, of target **vector**
 
  integer, intent(in)  :: izbeam  ! Z of beam species
  integer, intent(in)  :: iztarg  ! Z of target species
 
  !  **result**
 
  real*8, intent(out) :: btsigv(n)   ! <sigma*v>, m**3/sec  **vector**
                                     ! or <Eav>, KeV
                                     ! or <fd>, dimensionless
 
  integer, intent(out) :: istat      ! completion code; 0 = normal
 
  !  istat = 1:  beamchrg argument invalid
  !  istat = 2:  irtype argument invalid
  !  istat = 3:  izbeam or iztarg invalid
  !
  !--------------------------------------------
  !  local
 
  integer :: lreact   ! reaction handle
  integer :: izneut   ! Z of neutral
  integer :: izchrg   ! Z of charged ptcl
 
  !--------------------------------------------
  !  initialize module, if necessary
 
  if(hatom_flag.eq.0) call hatom_init
 
  !--------------------------------------------
 
  istat = 0
  lreact = IZERO
 
  if(beamchrg.eq.NEUTRAL) then
 
     !  ---------> Neutral Beam, charged particle target
 
     izneut = izbeam
     izchrg = iztarg
 
  else if(beamchrg.eq.ION) then
 
     izneut = iztarg
     izchrg = izbeam
 
  else
 
     istat = 1
     btsigv = ERROR
     return
 
  endif
 
  if((irtype.eq.CX).or.(irtype.eq.EAV).or.(irtype.eq.FD)) then
 
     !  ---------> (neutralizing) charge exchange
 
     if(izneut.eq.H) then
        if(izchrg.eq.H) then
           lreact = Lcx_H0_H
        else if(izchrg.eq.HE) then
           lreact = IZERO          ! cannot neutralize HE
        else if(izchrg.eq.LI) then
           lreact = IZERO          ! cannot neutralize LI
        else
           istat = 3
           lreact = IERROR
        endif
 
     else if(izneut.eq.HE) then
        if(izchrg.eq.H) then
           lreact = Lcx_HE0_H
        else if(izchrg.eq.HE) then
           lreact = Lcx_HE0_HE
        else if(izchrg.eq.LI) then
           lreact = IZERO          ! cannot neutralize LI
        else
           istat = 3
           lreact = IERROR
        endif
 
     else if(izneut.eq.LI) then
        if(izchrg.eq.H) then
           lreact = Lcx_LI0_H
        else if(izchrg.eq.HE) then
           lreact = Lcx_LI0_HE
        else if(izchrg.eq.LI) then
           lreact = Lcx_LI0_LI
        else
           istat = 3
           lreact = IERROR
        endif
 
     else
 
        istat = 3
        lreact = IERROR
 
     endif
 
  else if(irtype.eq.II) then
 
     !  ---------> impact ionization
     !      or, sum of impact ionization and partial charge exchange
 
     if(izneut.eq.H) then
        if(izchrg.eq.H) then
           lreact = Lii_H0_H
        else if(izchrg.eq.HE) then
           lreact = Lii_H0_HE
        else if(izchrg.eq.LI) then
           lreact = Lii_H0_LI
        else
           istat = 3
           lreact = IERROR
        endif
 
     else if(izneut.eq.HE) then
        if(izchrg.eq.H) then
           lreact = Lii_HE0_H
        else if(izchrg.eq.HE) then
           lreact = Lii_HE0_HE
        else if(izchrg.eq.LI) then
           lreact = Lii_HE0_LI
        else
           istat = 3
           lreact = IERROR
        endif
 
     else if(izneut.eq.LI) then
        if(izchrg.eq.H) then
           lreact = Lii_LI0_H
        else if(izchrg.eq.HE) then
           lreact = Lii_LI0_HE
        else if(izchrg.eq.LI) then
           lreact = Lii_LI0_LI
        else
           istat = 3
           lreact = IERROR
        endif
 
     else
 
        istat = 3
        lreact = IERROR
 
     endif
 
  else
     istat = 2
     lreact = IERROR
  endif
 
  if(lreact.eq.IZERO) then
 
     btsigv = ZERO
 
  else if(lreact.eq.IERROR) then
 
     btsigv = ERROR
 
  else
 
     if(irtype.eq.CX) then
 
        call cx_warmtarget_sigmatimesv(lreact, eabeam, tatarg, btsigv, n)
 
     else if(irtype.eq.EAV) then
 
        call cx_energyavg_peramu(lreact, eabeam, tatarg, btsigv, n)
 
     else if(irtype.eq.FD) then
 
        call cx_average_vdotnorm(lreact, eabeam, tatarg, btsigv, n)
 
     else if(irtype.eq.II) then
 
        call ii_warmtarget_sigmatimesv(lreact, eabeam, tatarg, btsigv, n)
 
     endif
 
  endif
 
end subroutine hatom_btsigv
