module get_fbm_module
!
  use iso_c_binding, only: fp => c_double
  use physconst_mod, only: xpi=>pi, xe=>kb_eV
  implicit none
  private :: fp
  SAVE
!
!  get_fbm shared quantities -- allocatable data arrays and
!  dimensioning information (dmc 7 Aug 2000)
!
  real(fp), dimension(:,:,:,:), allocatable :: fbm ! dist. fcn at GC
!MG
  real(fp), dimension(:,:,:,:), allocatable :: fbm_ptcl ! dist. fcn at ptcl. position, 4D function
  real(fp), dimension(:,:,:,:,:), allocatable :: fbm_ptcl5 ! dist. fcn at ptcl. position, 5D function
  real(fp), dimension(:,:), allocatable :: efbmb ! energy grid
!
!  dE, d(pa), pa grid:
  real(fp), dimension(:), allocatable :: efbm,delten
  real(fp), dimension(:), allocatable :: deltpa,deltvpv,xxksid,xksidb
!
!  Ab,Zb arrays:
  real(fp), dimension(:), allocatable :: abeams,xzbeams
  
  integer :: nenb                      ! # of E grid bdys  (array dim.)
  integer :: nenz                      ! # of E grid zones (array dim.)
  integer :: npazns                    ! # of pitch angle zones (array dim.)
  integer :: nznsi                     ! # of fbm spatial zones (array dim.)
  integer :: ngyro                     ! # of fbm poloidal aim.angle (array dim.)
  integer :: nfast                     ! # of fast ion species (array dim.)
  integer :: nvol                      ! # of extended spatial zones (dim.)
  integer :: ntbl                      ! size of theta zone row ptr table
  
  integer :: mtbl                      ! bloated radial grid array size
  integer :: mimom                     ! max no. fourier moments
  
  integer :: mj                        ! rmom0,rmom,ymom,rmc,ymc dimension
  integer :: miz                       ! ditto
  
  integer :: nmom                      ! actual no. of moments, this run
  
  integer :: nzones                    ! no. of radial zones
  
  ! the following TRANSP-legacy info can be omitted in NetCDF I/O:
  integer :: nxskpb = 0             ! MC grid zone skip factor
  integer :: nxtbzn = 0             ! # of MC grie zone rows beyond bdy
  
  logical :: nlsym                     ! updown symmetry flag
  real(fp) :: thbdy0,thbdy1              ! theta range of fbm
  
  real(fp) :: ta                         ! time of data
  real(fp) :: dta                        ! +/- dta (averaging half-time)
  
  integer :: ns,nsuse                        ! specie index
  real(fp) :: abeam,xzbeam               ! Ab, Zb of selected fast specie.
  integer :: nenergy                   ! #of energy zones this specie.
  
  real(fp) :: xminbm                     ! extent of x grid for fbm
  
  real(fp), dimension(:), allocatable :: bmvol,bmvolinv
  real(fp), dimension(:,:), allocatable :: bdens2,eba2pl,eba2pp
  real(fp), dimension(:,:), allocatable :: bbnvol,btntn2
  real(fp), dimension(:,:), allocatable ::  bbntns,btntns
  real(fp), dimension(:), allocatable :: xi,xib,dxi
  
  !  actual energy grid sizes; table of pointers for fbm spatial zone rows:
  integer, dimension(:), allocatable :: nznbmea,nthzsm
  !
  !  for equilibrium -- real(fp) :: conversion done
  !
  real(fp), dimension(:,:), allocatable :: xitr  ! TRANSP xi(mj,miz)
  !
  real(fp), dimension(:), allocatable :: xiblo,rmb0
  real(fp), dimension(:,:), allocatable :: rmb0s,rmb2,ymb2
  real(fp), dimension(:,:,:), allocatable :: rmb2s,ymb2s
  !  (asymmetric)
  real(fp), dimension(:,:,:), allocatable :: rmcx,ymcx
  real(fp), dimension(:,:,:,:), allocatable :: rmcxs,ymcxs
  !
  real(fp), dimension(:,:), allocatable :: rmom0
  real(fp), dimension(:,:,:), allocatable :: rmom,ymom,rmc,ymc
  !
  !  for gmomry -- real(fp) :: conversion done
  !
  real(fp), dimension(:), allocatable :: RMSPLC,RMSPLS,YMSPLC,YMSPLS
  real(fp) :: R0SPL
  real(fp), dimension(:), allocatable :: RMSPL,YMSPL
  !
  real(fp), dimension(:), allocatable :: DRMDROC,DRMDROS, &
       DYMDROC,DYMDROS
  real(fp) :: DR0DRO
  real(fp), dimension(:), allocatable :: DRMDRO,DYMDRO
  !
  !  namelist control -- 15'th element is non-zero of FBM is accumulated
  !  at guiding centers
  !
  real(fp), dimension(:), allocatable :: gflr_op
  logical :: znewmhd
  !
  !  for UFILES
!
  character(len=4) :: tdev
  character(len=16) :: udisk
  character(len=128) :: uarea,uarea0
  
  !  Ufile scalar data
  
  integer, parameter :: nscmax = 100 ! max number
  integer :: nsc                    ! actual number
  character(10), dimension(3,nscmax) :: labels ! labels
  real(fp), dimension(nscmax) :: values ! values
  
  !  actual center zone index, #of species, #of pitch angles, #radial zones
  
  integer :: lcentr,ledge
  integer :: nsbeam, nsfast,nznbma, nznbmr
  integer :: nbeamline !#of beam lines
  !  #of r-rows covered by fbm
  integer :: nznbmrf
  
  integer :: nshot                     ! shot number
  
  !  fast ion species types
  !    nsbeam.lt.j.le.nsfast => species j is RF minority
  !    j.le.nsbeam:  nlfprod(j)=.TRUE. => species j is a fusion product
  !                         otherwise  => species j is a neutral beam ion
  
  logical, dimension(:), allocatable :: nlfprod
  integer, dimension(:), allocatable :: ktype
  integer :: curtype
  
  !  fast ion species type labeling
  character(len=4) :: fitype(3)
  character(len=10) :: wd1(3),wd2(3),wd3(3)
  character(len=20) :: filbl(3)
  !
  !  coordinate ids
  integer, parameter :: kenergy = 1
  integer, parameter :: kpitch = 2
  integer, parameter :: kx = 3
  integer, parameter :: ktheta = 4
  !
  real(fp) :: energy0,energy1
  real(fp) :: pitch0,pitch1
  real(fp) :: x0,x1
  real(fp) :: theta0,theta1
  !
  !  averaging weights & work arrays
  !
  real(fp), dimension(:), allocatable :: wt_e,wt_vpv,wt_x,wt_th
  real(fp) :: del_e,del_vpv,del_x,del_th
  real(fp), dimension(:), allocatable :: fdxa,dxa
  integer :: ix_select,idxa
  !
  !  local theta array (at particular x zone row)
  !
  real(fp), dimension(:), allocatable :: th_lcl,dth_lcl
  integer :: nth_lcl
  !
  integer, parameter :: iflat = 1
  integer, parameter :: iperiodic = 2
  !
  !  distribution function slice arrays
  !
  real(fp), dimension(:,:,:), allocatable :: fdis  ! f(E,vpll/v,r)
  real(fp), dimension(:,:), allocatable :: fdisrt  ! f(E,vpll/v)
  real(fp), dimension(:,:), allocatable :: fdish   ! f(E,r)
  real(fp), dimension(:), allocatable :: fslice    ! f(E) or f(vpll/v) ...
  !
  real(fp), dimension(:), allocatable :: dvolth    ! dvol[theta0,theta1]
  real(fp) :: volume                       ! dvol[theta0,theta1,x0,x1]
  real(fp), dimension(:,:), allocatable :: dvol ! EXACT VOLUME OF JTH ZONE (CM**3), bdy(1)/zone(2) shift index
  !
  !----------------------------------------------------------------------
  !  dmc: new May 2007: deposition distribution function data, in form
  !       of neutral tracks with deposition probability profiles for each
  !       track
  !
  logical :: nldeptrk ! T if this data is available
  logical :: nlfbm_ptcl = .FALSE.! T if FBM and FBM_PTCL are available, set JUNE 01,2011 (MG)
  logical :: nlfbm_gc = .TRUE. !FBM at GC, set JUNE 01,2011 (MG)
  !
!  for beams:
  integer :: mztrack  ! max no. of zones per track
  integer :: mntrack  ! max no. of tracks
  !
  !  for fusion products:
  !
  integer :: mireact  ! reaction index dimension
  !     FUSION REACTIONS
  !  0'S FOR COMPUTED FUSION REACTIONS THAT do NOT PRODUCE NEUTRONS
  !  also a 0 for the fusion-product burnup neutrons category (#9)
  !  and the RF tail burnup neutrons categories (#11 and #13)
  !  which are counted separately cf SUMNTX.FOR (DMC 17 Oct 1991, & 1997)
  !
  integer, parameter :: inreact=18 ! # of reaction  FUSION REACTIONS THAT
  integer :: INEUTS(inreact) !consistent with mireact in port.spec
  !
  DATA INEUTS/1,0,0,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0/
  !
  ! bbnvol(:,1) -- DT BEAM-BEAM NEUTRONS
  ! bbnvol(:,2) -- DHE3 BEAM-BEAM FUSION
  ! bbnvol(:,4) -- DD BEAM-BEAM NEUTRONS
  ! bbnvol(:,5) -- TT BEAM-BEAM NEUTRONS
  ! bbnvol(:,9) -- FUSION T BURNUP ON BEAM D
  ! bbnvol(:,10) --FUSION HE3 BURNUP ON BEAM D
  !
  ! btntn2(:,1) -- DT BEAM-TARGET NEUTRONS
  ! btntn2(:,2) -- DHE3 BEAM-TARGET FUSION
  ! btntn2(:,4) -- DD BEAM-TARGET NEUTRONS
  ! btntn2(:,5) -- TT BEAM-TARGET NEUTRONS
  ! btntn2(:,7) -- TD BEAM-TARGET NEUTRONS
  ! btntn2(:,8) -- HE3D BEAM-TARGET FUSION
  ! btntn2(:,9) -- FUSION T BURNUP ON THERMAL D
  ! btntn2(:,10) --FUSION HE3 BURNUP ON THERM D
  character(len=28), dimension(inreact) :: cbbn
  character(len=28), dimension(inreact) :: cbtn
  DATA  cbbn/ &
       'DT BEAM-BEAM NEUTRONS       ', &
       'DHE3 BEAM-BEAM FUSION       ', &
       '                            ', &
       'DD BEAM-BEAM NEUTRONS       ', &
       'TT BEAM-BEAM NEUTRONS       ', &
       '                            ', &
       '                            ', &
       '                            ', &
       'FUSION T BURNUP ON BEAM D   ', &
       'FUSION HE3 BURNUP ON BEAM D ', &
       8*'                            '/
  DATA  cbtn/ &
       'DT BEAM-TARGET NEUTRONS     ', &
       'DHE3 BEAM-TARGET FUSION     ', &
       '                            ', &
       'DD BEAM-TARGET NEUTRONS     ', &
       'TT BEAM-TARGET NEUTRONS     ', &
       '                            ', &
       'TD BEAM-TARGET NEUTRONS     ', &
       'HE3D BEAM-TARGET FUSION     ', &
       'FUSION T BURNUP ON THERMAL D', &
       'FUSION HE3 BURNUP ON THERM D', &
       8*'                            '/
  !
  logical, dimension(:,:), allocatable :: nlfusion_sce
  real(fp), dimension(:,:), allocatable :: efusion_sce
  real(fp), dimension(:,:), allocatable :: fusion_sce
  real(fp), dimension(:), allocatable :: sftot
  real(fp), dimension(:), allocatable :: omegag
  real(fp), dimension(:), allocatable :: TOTNTNF ! GRAND TOTAL NEUTRON EMISSIVITY PROFILE #/SEC/ZONE
  real(fp), dimension(:), allocatable :: THNTNT !  THERMONUCLEAR NEUTRONS EMISSIVITY PROFILE #/SEC/ZONE
  real(fp) :: TOTNTNS ! GRAND TOTAL NEUTRONS PRODUCED #/SEC
  !
  !  (array dimension nfast also used...)
  !
  logical, dimension(:), allocatable :: nldep_beam,nldep_fusion
  !
  integer, dimension(:), allocatable :: mibs2use !maps lsbeam/isb to mibs_use
  integer, dimension(:), allocatable :: ntracks
  integer :: nzmax_track,nstep_gtime,ndep0_use,ndep0
  integer :: mtrk0 !total zone #
  integer, dimension(:,:), allocatable :: nztrack
  integer, dimension(:), allocatable :: nztrack_s ! # of zone per species
  
  real(fp) :: track_gtime1,track_gtime2
  real(fp), dimension(:,:), allocatable :: track_rin,track_zin, &
       track_phiin
  real(fp), dimension(:,:), allocatable :: track_rout,track_zout, &
       track_phiout
  real(fp), dimension(:,:), allocatable :: track_time,track_einj, &
       track_sinj
  
  integer, dimension(:,:), allocatable :: ntrack_nbsce !beam index
  integer, dimension(:,:), allocatable :: ntrack_nbien ! energy fraction index
  integer :: iversion_deptrk ! =1 - no data for ntrack_nbsce and ntrack_nbien in black box
  ! =2 there are data for ntrack_nbsce and ntrack_nbien
  
  integer :: nfast_use
  
  !for iversion_deptrk = 3, track data array are  1D
  integer, dimension(:), allocatable :: nstat_track_xja
  integer, dimension(:), allocatable :: mztrack_s ! # of zone per species
  real(fp), dimension(:), allocatable :: track_xl,track_pdep
  real(fp), dimension(:), allocatable :: track_dr_flr, &
       track_dz_flr,track_de_flr
  real(fp), dimension(:), allocatable :: track_vpv_dep, &
       track_dvpv_flr

  !for iversion_deptrk = 2, track data arrays are  3D
  integer, dimension(:,:,:), allocatable :: nstat_track3_xja
  real(fp), dimension(:,:,:), allocatable :: track3_xl,track3_pdep
  real(fp), dimension(:,:,:), allocatable :: track3_dr_flr, &
       track3_dz_flr,track3_de_flr
  real(fp), dimension(:,:,:), allocatable :: track3_vpv_dep, &
       track3_dvpv_flr
  !
  !----------------------------------------------------------------------
  !  labeling:  for Ufiles & graphics
  character(30) :: fdis_units
  character(30) :: eunits = 'Energy              eV        '
  character(30) :: vunits = 'Pitch               vpll/v    '
  character(30) :: xunits = 'x                   ~(r/a)    '
  character(30) :: thunits= 'theta               radians   '
  
  !
  !----------------------------------------------------------------------
  ! lost orbit data
  !
  logical :: nllost   ! T if this data is available
  integer :: mlost_data !# of lost orbit
  real(fp), dimension (:), allocatable :: gtime_lost, ynbsce_lost ! time, beam#
  real(fp), dimension (:), allocatable :: ynbien_lost,wght_lost   ! energy frc #, ptcl#
  real(fp), dimension (:), allocatable :: rmjion_lost,yyion_lost  ! R,Z [cm]
  real(fp), dimension (:), allocatable :: yze_lost, xksid_lost     ! energy [kev],vll/v
  real(fp), dimension (:), allocatable :: goose_lost, species_lost !species
  real(fp) :: GTIME1_LOST, GTIME2_LOST !time begining, ending  gathering data
  !
  !----------------------------------------------------------------------
  ! beam info
  !
  real(fp), dimension(:), allocatable ::  znlco ! direction of beam injection
  !1. = 'co', 0. = 'counter' injected
  real(fp), dimension (:), allocatable :: pinja,pinja_use !injected beam power by beam
  real(fp), dimension (:), allocatable :: xninjs ! # injected beam ptcl by species
  real(fp), dimension (:), allocatable :: xbzeta ! toroidal angle of beam source in an (R,zeta,Z), deg
  real(fp), dimension (:), allocatable :: rtcena ! tangency major radius, cm, of centerline of beam
  real(fp), dimension (:), allocatable :: xlbapa ! distance, beam source grid to aperture, cm
  real(fp), dimension (:), allocatable :: xlbtna ! distance, cm, from center of beam source grid
  ! to tangency point, cm
  integer :: nbeam ! number of beamlines
  character(len=3), dimension(:), allocatable :: beam_inj !0:nbeam, tag for beam injection
  integer :: nsjdotb ! +1 if Ip and Bt are parallel, -1 if anti-pll
  integer :: nsnccw  ! +1 if Bphi is CCW looking down on tokamak from above
  ! -1 otherwise
end module get_fbm_module
