subroutine nbi_datchk(ierr)
 
  use nbi_com
  use nbi_mpi_com
  implicit none
  integer, intent(out) :: ierr        ! completion code, 0=ok
 
  !
  !  check control input quantities (things which generally do not vary
  !  in time) and calculate derived quantities.
  !
  !  in the nbi modules:
  !  the inputs are:
  !    --lun for messages:  nonlin
  !    --the maximum no. of fast species:  mibs
  !    --list of thermal plasma species (aplasm(1:ng),backz(1:ng))
  !    --list of rf minority species (amini(1:nmini),xzmini(1:nmini))
  !    --list of neutral beams (abeama(1:nbeam),xzbeama(1:nbeam))
  !      & logical switch nlbfpp
  !        (.t means fpp code does slowing down; nubeam for deposition only).
  !      & ebdmax = max energy for fast ion dist. fcn (fbm) calculation
  !      & nznbme = #energy zones in fbm calculation
  !
  !    --fusion product logical switches
  !        nlfst nlfsp nlfsp14 nlfhe3 nlfhe4
  !      & associated threshhold powers
  !        plfst plfsp plfsp14 plfhe3 plfhe4
  !
  !    --for fast ion distribution function velocity space grids:
  !        ebdmax -- max energy for beams
  !        nznbme -- no. of energy zones
  !        nznbma -- no. of pitch angle zones
  !
  !  the outputs are:
  !    nhydr,ndeut,ntrit,nhel3,nhel4,nlith ! thermal specie indices
  !    nbhydr,nbdeut,nbtrit,nbhel3,nbhel4 ! beam specie indices
  !       nlheavy -- heavy beam ion flag
  !    nfprot,nftrit,nfhel3,nfhel4        ! fusion product specie indices
  !    nrfhydr,nrfdeut,nrftrit,nrfhel3,nrfhel4  ! rf minority indices
  !    mrfhydr,mrfdeut,mrftrit,mrfhel3,mrfhel4  ! rf minority indices
  !
  !      abeams,xzbeams,einjs,nznbmea,nznblea,...
  !      nlfbmfpp,nlmcany,...
  !
  !    nsbeam -- no. of beam & fusion product species
  !    nsfast -- nsbeam + no. of rf minority species
  !-------------------------------------------------
  !  local variables e.g. loop indices
 
  integer iwarn
  integer ib,isb,isbeam,imatch
  integer ierff,ierfh,ierfs
  integer idmax
 
  real(fp) :: zemax
  logical :: il_loggrid
  integer :: i
 
  !-------------------------------------------------
  !  de facto constants
  !  these quantities are hardwired in the module.
 
  nlfbm=.true.  ! always compute fast ion distribution fcns
 
  !-------------------------------------------------
 
  ierr=0
  iwarn=0
 
  !-------------------------------------------------
  !  grid checks...
 
  if((nzones.lt.5).or.(nzones.gt.(mj-3))) then
     write(nonlin,*) ' ?nbi_datchk:  nzones = ',nzones
     write(nonlin,*) '  minimum allowed: 5'
     write(nonlin,*) '  maximum allowed:  mj-3 = ',mj-3
     write(nonlin,*) '    (user can set mj, cf nbi_set_dims(...))'
     write(nonlin,*) '    (user can set nzones, cf nbi_set_grid(...))'
     ierr=1
  endif
 
  if(nznbma.gt.mimxba) then
     write(nonlin,*) ' ?nbi_datchk: error in pitch angle grid:'
     write(nonlin,*) '  nznbma = ',nznbma,' exceeds mimxba = ',mimxba
     write(nonlin,*) '    (user can set mimxba, cf nbi_set_dims(...))'
     write(nonlin,*) '    (user can set nznbma, cf nbi_set_grid(...))'
     ierr=1
  endif
 
  if(nznbme.gt.mimxbe) then
     write(nonlin,*) ' ?nbi_datchk: error in energy grid:'
     write(nonlin,*) '  nznbme = ',nznbme,' exceeds mimxbe = ',mimxbe
     write(nonlin,*) '    (user can set mimxbe, cf nbi_set_dims(...))'
     write(nonlin,*) '    (user can set nznbme, cf nbi_set_grid(...))'
     ierr=1
  endif
  if(ngyro.gt.mgyro) then
     write(nonlin,*) ' ?nbi_datchk: error in poloidal angle grid:'
     write(nonlin,*) '  ngyro = ',ngyro,' exceeds mgyro = ',mgyro
     write(nonlin,*) '    (user can set mgyro, cf nbi_set_dims(...))'
     write(nonlin,*) '    (user can set ngyro, cf nbi_set_grid(...))'
     ierr=1
  endif
  if(mgyro.le.0) then
     write(nonlin,*) ' ?nbi_datchk: error in poloidal angle grid:'
     write(nonlin,*) '  mgyro = ',mgyro
     write(nonlin,*) '    (user can set mgyro, cf nbi_set_dims(...))'
     ierr=1
  endif
  if(ngyro.le.0) then
     write(nonlin,*) ' ?nbi_datchk: error in poloidal angle grid:'
     write(nonlin,*) '  ngyro = ',ngyro
     write(nonlin,*) '    (user can set ngyro, cf nbi_set_grid(...))'
     ierr=1
  endif
  
  !-------------------------------------------------
  !  thermal specie indices
 
  if(ngmax.gt.mig) then
     write(nonlin,*) ' ?nbi_datchk: error in no. of thermal gases:'
     write(nonlin,*) '  ngmax = ',ngmax,' exceeds mig = ',mig
     write(nonlin,*) '    (user can set mig, cf nbi_set_dims(...))'
     write(nonlin,*) '    (user can set ngmax, cf nbi_set_beams(...))'
     ierr=1
  else
     call r8_nbi_datchki(nonlin,ngmax,aplasm,backz, &
          nhydr,ndeut,ntrit,nhel3,nhel4,nlith,iwarn,ierr)
     if(iwarn.gt.0) ierr=ierr+1
  endif
 
  !--------------------------------------------
  !  impurities & rf minorities
 
  if(nrhix.gt.mimpt) then
     write(nonlin,*) ' ?nbi_datchk: error in no. impurities:'
     write(nonlin,*) '  nrhix = ',nrhix,' exceeds mimpt = ',mimpt
     write(nonlin,*) '    (user can set mimpt, cf nbi_set_dims(...))'
     write(nonlin,*) '    (user can set nrhix, cf nbi_set_impurity(...))'
     ierr=1
  endif
 
  if(nmini.gt.mmini) then
     write(nonlin,*) ' ?nbi_datchk: error in no. of rf minorities:'
     write(nonlin,*) '  nmini = ',nmini,' exceeds mmini = ',mmini
     write(nonlin,*) '    (user can set mmini, cf nbi_set_dims(...))'
     write(nonlin,*) '    (user can set nmini, cf nbi_set_minority(...))'
     ierr=1
  endif
 
  !--------------------------------------------
  !  beam species
  !
 
  if(nbeam.gt.mib) then
     write(nonlin,*) ' ?nbi_datchk: error in no. of beams:'
     write(nonlin,*) '  nbeam = ',nbeam,' exceeds mib = ',mib
     write(nonlin,*) '    (user can set mib, cf nbi_set_dims(...))'
     write(nonlin,*) '    (user can set nbeam, cf nbi_set_beams(...))'
     ierr=1
  else
     call r8_nbi_datchkb(nonlin,nbeam,abeama,xzbeama, &
          mibs,abeams,xzbeams,nsbeam, &
          nbhydr,nbdeut,nbtrit,nbhel3,nbhel4,nlheavy,ierr)
  endif
 
  ! for each beam there must be a corresponding thermal specie
 
  call ckth(nbhydr,nhydr,'h beam','h')
  call ckth(nbdeut,ndeut,'d beam','d')
  call ckth(nbtrit,ntrit,'t beam','t')
  call ckth(nbhel3,nhel3,'he3 beam','he3')
  call ckth(nbhel4,nhel4,'he4 beam','he4')
 
  nlfbmfpp=.false.
  if(nlbfpp) then
     do isb=1,nsbeam
        if(.not.nlheavy(isb)) nlfbmfpp(isb)=.true.
     enddo
  endif
 
  isbeam=nsbeam   ! remember no. of beams as nsbeam may get incremented...
 
  ebdmaxa(1:isbeam)=ebdmax
  nznbmea(1:isbeam)=nznbme
 
  !--------------------------------------------
  ! fusion products

  nptclf=max(10,nptclf)   ! assure at least a few mc particles
 
  nlfprod=.false.
  call r8_nbi_datchkf(nonlin,nlfsp,nlfsp14,nlfst,nlfhe3,nlfhe4, &
       mibs,nsbeam,mimxbe,nlfprod, &
       ebdmaxa,nznbmea,einjs,abeams,xzbeams, &
       nfprot,nfprot14,nftrit,nfhel3,nfhel4,ierr)
 
  plfsp=max(epslon,plfsp)
  plfsp14=max(epslon,plfsp14)
  plfst=max(epslon,plfst)
  plfhe3=max(epslon,plfhe3)
  plfhe4=max(epslon,plfhe4)
 
  if(nsbeam.gt.isbeam) then
     nlfusn=.true.
  else
     nlfusn=.false.  ! there are no fusion products in this run
  endif
 
  ! note:  a thermal specie matching the fusion product specie not required.
 
  !--------------------------------------------
  !  compute the energy grids
  il_loggrid=.false.
 
  do isb=1,nsbeam
     if(orbrzv_rf_option.eq.1.or.abs(ntest_max).eq.1) then
        zemax=edbfac*ebdmaxa(isb) !must be consistent with trcore/datckb.for
        il_loggrid=.true.
        ! force to set nerngfi = 1 for a rf or maxwellian test
        erngfi(1,isb)=zemax
        do i=1,miefi
           if(erngfi(i,isb).le.zero) go to 1001
        enddo
        i=miefi+1
1001    continue
        nerngfi=i-1
        if(nerngfi.gt.0) then
           do i=1,nerngfi-1
              if(erngfi(i+1,isb).le.erngfi(i,isb)) then
                 ierr=1
                 write(nonlin,*)' ?nbi_datchk: erngfi-energies not in ascending order!'
               endif
            enddo
         endif
                  
     else
        zemax=ebdmaxa(isb)
     endif
     call r8_nbi_efbm(nlfprod(isb),il_loggrid,edbfac,nznbmea(isb),zemax,&
          nznblea(isb),ebdlina(isb),efbmb(1,isb),efbm(1,isb))
  enddo

 
  !--------------------------------------------
  !  rf species...
 
  nsfast=nsbeam
 
  call r8_nbi_datckrf(nonlin,nmini,amini,xzmini,nrfmini, &
     mibs,nsfast,mrfmini,abeams,xzbeams,nlfbmfpp, &
     nrfhydr,nrfdeut,nrftrit,nrfhel3,nrfhel4, &
     mrfhydr,mrfdeut,mrftrit,mrfhel3,mrfhel4, &
     ierr)
 
  call chrf(nrfhydr,nhydr,'h')
  call chrf(nrfdeut,ndeut,'d')
  call chrf(nrftrit,ntrit,'t')
  call chrf(nrfhel3,nhel3,'he3')
  call chrf(nrfhel4,nhel4,'he4')
 
  !--------------------------------------------
  !  flag certain fusion reactions...
 
  nlddp=.false.
  if(nlfst.or.nlfsp) nlddp=.true.
  idmax=max(ndeut,nbdeut,nrfdeut)
  if(idmax.gt.0) nlddp=.true.
 
  !--------------------------------------------
  !  finish up...
 
  nlmcany=.false.
  do isb=1,nsfast
     nlmcany=nlmcany.or.(.not.nlfbmfpp(isb))
  enddo
 
  if(nlmcany) then
 
     if(dtn.le.zero) then
        ldtnfr=.true.    ! set dtn using raxis
     else
        ldtnfr=.false.
     endif
 
     if((nchdvp.le.0).or.(nchdvp.gt.3)) then
        write(nonlin,*) ' %nbi_datchk: nchdvp=',nchdvp, &
             ' out of range, reset to 3.'
        nchdvp=3
     endif
 
  endif
 
  !==========================================================
  !  a few trailing miscellaneous checks...
 

 
  lrunid = len_trim(runid)
  if(lrunid.eq.0) then
     write(nonlin,*) ' ?nbi_datchk:  runid = "',runid,'".'
     ierr=1
  endif
 
  ierff=0
  ierfh=0
  ierfs=0
  do ib=1,nbeam
     if((ffulla(ib).gt.one).or.(ffulla(ib).lt.zero)) then
        write(nonlin,*) ' ?nbi_datchk: ffulla(',ib,')=',ffulla(ib)
        ierff=ierff+1
     endif
     if((fhalfa(ib).gt.one).or.(fhalfa(ib).lt.zero)) then
        write(nonlin,*) ' ?nbi_datchk: fhalfa(',ib,')=',fhalfa(ib)
        ierfh=ierfh+1
     endif
     if((ffulla(ib)+fhalfa(ib)).gt.1.0001_fp) then
        write(nonlin,*) ' ?nbi_datchk: ib=',ib, &
             ' ffulla(ib)+fhalfa(ib) > 1.0:',ffulla(ib)+fhalfa(ib)
        ierfs=ierfs+1
     endif
  enddo
 
  if(ierff.gt.0) then
     ierr=1
     write(nonlin,*) ' '
     write(nonlin,*) ' all ffulla(...) values must be between 0.0 and 1.0'
  endif
 
  if(ierfh.gt.0) then
     ierr=1
     write(nonlin,*) ' '
     write(nonlin,*) ' all fhalfa(...) values must be between 0.0 and 1.0'
  endif
 
  if(ierff.gt.0) then
     ierr=1
     write(nonlin,*) ' '
     write(nonlin,*) ' all ffulla(ib)+hfalfa(ib) sums must be <= 1.0'
  endif
 
 
  if(ierr.ne.0) then
     write(nonlin,*) ' ?nbi_datchk:  error detected in nubeam inputs.'
  endif

  if(ncx0.gt.0) then
     nper_cx=max(1,nper_cx) ! assure at least one gyro phase angle
  endif
     
 
  !==========================================================
 
  contains
 
    subroutine ckth(ibi,ithi,zlblb,zlblth)

      integer ibi,ithi  ! beam & thermal indices
      character*(*) zlblb,zlblth  ! strings for error message
 
      if((ibi.gt.0).and.(ithi.eq.0)) then
         write(nonlin,*) '%nbi_datchk: ',zlblb,' has no ',zlblth, &
              ' thermal specie.'
      endif
 
    end subroutine ckth
 
    subroutine chrf(irfi,ithi,zlbl)
 
      integer irfi,ithi  ! rf & thermal indices
      character*(*) zlbl
 
      if(irfi.gt.0) then
         if(ithi.gt.0) then
            write(nonlin,*) '%nbi_datchk: detected both ',zlbl, &
                 ' rf tail and ',zlbl,' thermal species.'
         endif
      endif
 
    end subroutine chrf
 
end subroutine nbi_datchk
! 11sep2004 fgtok -s r8_precision.sub nubeam_test_r8.sub "r8con.csh conversion"
