module echmod_typedef

  ! define datasets used by TRANSP-related tools, to communicate with
  ! ECH models

  integer, parameter :: imaxan_tor = 7 ! max no. of Gaussian anulli (TORAY)

  type :: toray_numeric

     ! GA-TORAY numerical and logical controls
     !  (names originally from TRANSP, trcom, freeshare/port.spec)

     INTEGER :: igafit = 1     ! Switch to call gafit efit interface
     REAL*8  :: smax = 0.0d0   ! max arclength of array
     REAL*8  :: ds = 0.5d0     ! initial step size (cm)
     REAL*8  :: dsmin = 0.25d0 ! min step size (cm)

     REAL*8  :: fdout = 5.00d0 ! ray output step (every fdouttor cm)
     REAL*8  :: powinc = 1.0d13  ! for CQL3D J/P profile
     REAL*8  :: relerr = 5.0d-5  ! rel. error tolerance, y solution 
     REAL*8  :: abserr = 5.0d-5  ! abs. error tolerance in ODE solver

     INTEGER :: nharm = 2      ! harmonic; freq = nharm*[fundamental freq].
     INTEGER :: mn0 = 32       ! number of mesh pts in Gaussian integration
     !                           ...of Green's function in J/P resonance calc.

     INTEGER :: gauszone = 4   ! no. of annulli for Gaussian ray pattern

     INTEGER :: mray(imaxan_tor)   ! no. of rays in each Gaussian annulus
     REAL*8 :: cr(imaxan_tor)      ! azimuthal phase in each Gaussian annulus

     INTEGER :: modelc = 4     ! ECCD model selector (Lin-Liu = 4)
     REAL*8 :: pwrfmin = 0.001d0   ! cutoff power fraction

     LOGICAL :: netcdfdat = .TRUE. ! T for NetCDF output
     LOGICAL :: cqldat = .FALSE.   ! T for CQL3D output

     REAL*8 :: ezeff = 2.0d0   ! Default Zeff (usually overridden by data)
     REAL*8 :: bsratio = 1.0d0 ! Default beam elongation (1=circle)

  end type toray_numeric

  type :: toray_gafit

     ! GA-TORAY information on Psi(R,Z) & equilibrium input

     INTEGER :: ipsi = 0          ! 0 for psiin; 1 for g-eqdsk
     REAL*8 :: gafsep = 1.0d-2 
     REAL*8 :: dsrat = 2.0d-1
     REAL*8 :: percenflux = 1.0d0 ! ...to separatrix
     REAL*8 :: tolmap = 1.0d-10
     LOGICAL :: newbdry = .FALSE.

  end type toray_gafit

CONTAINS

  subroutine toray_numeric_adflts(tn)

    ! set array defaults 
    !   (scalar defaults set in declarations)

    type (toray_numeric) :: tn

    tn%mray(1) = 1
    tn%mray(2) = 5
    tn%mray(3) = 12
    tn%mray(4) = 12
    tn%mray(5) = 20
    tn%mray(6) = 24
    tn%mray(7) = 26

    tn%cr(1) = 0.0d0
    tn%cr(2) = 0.1d0
    tn%cr(3) = 0.05d0
    tn%cr(4) = -0.05d0
    tn%cr(5) = 0.05d0
    tn%cr(6) = -0.025d0
    tn%cr(7) = 0.025d0

  end subroutine toray_numeric_adflts

  subroutine toray_namelist_wr(zlabel, tn, tg, ier)

    !----------------------------------
    ! write "toray.in" and "gafit.in" namelist files for TORAY standalone code
    !----------------------------------

    use key_access

    !----------------------------------
    character*(*), intent(in) :: zlabel
    type (toray_numeric), intent(in) :: tn
    type (toray_gafit), intent(in) :: tg
    integer, intent(out) :: ier
    !----------------------------------
  
    integer :: ios,ilun

    !----------------------------------
    ier = 0
  
    call ka_init

    ! numerics
    call ka_set('igafit', tn%igafit) ! must be 1 for geqdsk 
    call ka_set('smax', tn%smax)   ! max arclength in cm
    call ka_set('ds', tn%ds)       ! initial step size in cm
    call ka_set('dsmin', tn%dsmin) ! adjustable step size in cm

    call ka_set('fdout', tn%fdout) ! ray output every fdout step 
    call ka_set('powinc', tn%powinc) ! for getting J/P profile 
    call ka_set('relerr', tn%relerr) ! Relative error 
    call ka_set('abserr', tn%abserr) ! absolute error

    call ka_set('pwrfmin', tn%pwrfmin) ! stop following when reach this fraction
    call ka_set('cqldat', tn%cqldat) ! Files for CQL3D 
    call ka_set('mn0', tn%mn0)     ! no of points in Gauss integration

    ! physics
    call ka_set('ezeff', tn%ezeff) ! Zrmeff
    call ka_set('nharm', tn%nharm) ! harmonic number
    call ka_set('bsratio', tn%bsratio) ! antenna elongation
    call ka_set('modelc', tn%modelc) ! model for ECCD calculation

    ! rays
    call ka_set('gauszone', tn%gauszone) ! no of zones 

    call ka_set('mray(1)',tn%mray(1))
    call ka_set('mray(2)',tn%mray(2))
    call ka_set('mray(3)',tn%mray(3))
    call ka_set('mray(4)',tn%mray(4))
    call ka_set('mray(5)',tn%mray(5))
    call ka_set('mray(6)',tn%mray(6))
    call ka_set('mray(7)',tn%mray(7))

    call ka_set('cr(1)',tn%cr(1))
    call ka_set('cr(2)',tn%cr(2))
    call ka_set('cr(3)',tn%cr(3))
    call ka_set('cr(4)',tn%cr(4))
    call ka_set('cr(5)',tn%cr(5))
    call ka_set('cr(6)',tn%cr(6))
    call ka_set('cr(7)',tn%cr(7))

    ! netcdf output
    call ka_set('netcdfdat', tn%netcdfdat)

    !------------------------------
    ! write toray.in ...

    call find_io_unit(ilun)

    open(ilun, file='toray.in', status='unknown', iostat=ios)
    if(ios.eq.0) then
       write(ilun,'(a)') trim(zlabel)
       close(ilun)
    else
       write(6,*) ' ?toray_namelist_wr: open failure: toray.in '
       ier=1
       return
    endif

    call ka_write_namelist('toray.in', 'EDATA', 'a') ! append mode
  
    call ka_free

    !-----------------------
    !  write gafit.in ...

    call ka_init
  
    call ka_set('ipsi', tg%ipsi)   ! 0 to use psiin generated above

    call ka_set('gafsep',tg%gafsep)
    call ka_set('dsrat', tg%dsrat)
    call ka_set('tolmap',tg%tolmap) ! tolerance
    call ka_set('percenflux', tg%percenflux) ! to separatrix
    call ka_set('newbdry', tg%newbdry)
    
    call ka_write_namelist('gafit.in', 'FITDAT', 'w')

    call ka_free

  end subroutine toray_namelist_wr

end module echmod_typedef
