korc_collisions.f90 Source File


This file depends on

sourcefile~~korc_collisions.f90~~EfferentGraph sourcefile~korc_collisions.f90 korc_collisions.f90 sourcefile~korc_profiles.f90 korc_profiles.f90 sourcefile~korc_collisions.f90->sourcefile~korc_profiles.f90 sourcefile~korc_fio_interface.f90 korc_fio_interface.f90 sourcefile~korc_collisions.f90->sourcefile~korc_fio_interface.f90 sourcefile~korc_interp.f90 korc_interp.f90 sourcefile~korc_collisions.f90->sourcefile~korc_interp.f90 sourcefile~korc_constants.f90 korc_constants.f90 sourcefile~korc_collisions.f90->sourcefile~korc_constants.f90 sourcefile~korc_types.f90 korc_types.f90 sourcefile~korc_collisions.f90->sourcefile~korc_types.f90 sourcefile~korc_hdf5.f90 korc_HDF5.f90 sourcefile~korc_collisions.f90->sourcefile~korc_hdf5.f90 sourcefile~korc_random.f90 korc_random.f90 sourcefile~korc_collisions.f90->sourcefile~korc_random.f90 sourcefile~korc_input.f90 korc_input.f90 sourcefile~korc_collisions.f90->sourcefile~korc_input.f90 sourcefile~korc_fields.f90 korc_fields.f90 sourcefile~korc_collisions.f90->sourcefile~korc_fields.f90 sourcefile~korc_profiles.f90->sourcefile~korc_interp.f90 sourcefile~korc_profiles.f90->sourcefile~korc_types.f90 sourcefile~korc_profiles.f90->sourcefile~korc_hdf5.f90 sourcefile~korc_profiles.f90->sourcefile~korc_input.f90 sourcefile~korc_hpc.f90 korc_hpc.f90 sourcefile~korc_profiles.f90->sourcefile~korc_hpc.f90 sourcefile~korc_coords.f90 korc_coords.f90 sourcefile~korc_profiles.f90->sourcefile~korc_coords.f90 sourcefile~korc_fio_interface.f90->sourcefile~korc_types.f90 sourcefile~korc_fio_interface.f90->sourcefile~korc_hdf5.f90 sourcefile~korc_fio_interface.f90->sourcefile~korc_input.f90 sourcefile~korc_interp.f90->sourcefile~korc_fio_interface.f90 sourcefile~korc_interp.f90->sourcefile~korc_types.f90 sourcefile~korc_rnd_numbers.f90 korc_rnd_numbers.f90 sourcefile~korc_interp.f90->sourcefile~korc_rnd_numbers.f90 sourcefile~korc_interp.f90->sourcefile~korc_hpc.f90 sourcefile~korc_interp.f90->sourcefile~korc_coords.f90 sourcefile~korc_constants.f90->sourcefile~korc_types.f90 sourcefile~korc_hdf5.f90->sourcefile~korc_constants.f90 sourcefile~korc_hdf5.f90->sourcefile~korc_types.f90 sourcefile~korc_hdf5.f90->sourcefile~korc_hpc.f90 sourcefile~korc_random.f90->sourcefile~korc_types.f90 sourcefile~korc_input.f90->sourcefile~korc_types.f90 sourcefile~korc_input.f90->sourcefile~korc_hpc.f90 sourcefile~korc_fields.f90->sourcefile~korc_interp.f90 sourcefile~korc_fields.f90->sourcefile~korc_types.f90 sourcefile~korc_fields.f90->sourcefile~korc_hdf5.f90 sourcefile~korc_fields.f90->sourcefile~korc_input.f90 sourcefile~korc_fields.f90->sourcefile~korc_hpc.f90 sourcefile~korc_fields.f90->sourcefile~korc_coords.f90 sourcefile~korc_rnd_numbers.f90->sourcefile~korc_types.f90 sourcefile~korc_rnd_numbers.f90->sourcefile~korc_random.f90 sourcefile~korc_hpc.f90->sourcefile~korc_types.f90 sourcefile~korc_coords.f90->sourcefile~korc_constants.f90 sourcefile~korc_coords.f90->sourcefile~korc_types.f90

Files dependent on this one

sourcefile~~korc_collisions.f90~~AfferentGraph sourcefile~korc_collisions.f90 korc_collisions.f90 sourcefile~korc_ppusher.f90 korc_ppusher.f90 sourcefile~korc_ppusher.f90->sourcefile~korc_collisions.f90 sourcefile~main.f90 main.f90 sourcefile~main.f90->sourcefile~korc_collisions.f90 sourcefile~main.f90->sourcefile~korc_ppusher.f90

Contents

Source Code


Source Code

module korc_collisions
  use korc_types
  use korc_constants
  use korc_HDF5
  use korc_interp
  use korc_profiles
  use korc_fields
  use korc_input

#ifdef FIO
  use korc_fio
#endif
  
#ifdef PARALLEL_RANDOM
  use korc_random
#endif

  IMPLICIT NONE

  CHARACTER(LEN=*), PRIVATE, PARAMETER 	:: MODEL1 = 'SINGLE_SPECIES'
  CHARACTER(LEN=*), PRIVATE, PARAMETER 	:: MODEL2 = 'MULTIPLE_SPECIES'
  REAL(rp), PRIVATE, PARAMETER 			:: infinity = HUGE(1.0_rp)

  TYPE, PRIVATE :: PARAMS_MS
     INTEGER 					:: num_impurity_species
     REAL(rp) 					:: Te
     ! Background electron temperature in eV
     REAL(rp) 					:: ne
     ! Background electron density in 1/m^3
     REAL(rp) 					:: nH
     ! Background proton density in 1/m^3
     REAL(rp) 					:: nef
     ! Free electron density in 1/m^3
     REAL(rp), DIMENSION(:), ALLOCATABLE        :: neb
     ! Bound electron density in 1/m^3
     REAL(rp), DIMENSION(:), ALLOCATABLE        :: Zi
     ! Atomic number of (majority) background ions
     REAL(rp), DIMENSION(:), ALLOCATABLE        :: Zo
     ! Full nuclear charge of each impurity: Z=1 for D, Z=10 for Ne
     REAL(rp), DIMENSION(:), ALLOCATABLE        :: Zj
     ! Atomic number of each impurity: Z=1 for D, Z=10 for Ne
     REAL(rp), DIMENSION(:), ALLOCATABLE        :: nz
     ! Impurity densities
     REAL(rp), DIMENSION(:), ALLOCATABLE        :: IZj,aZj
     ! Ionization energy of impurity in eV
     REAL(rp), DIMENSION(:), ALLOCATABLE        :: Ee_IZj
     ! me*c^2/IZj dimensionless parameter

     REAL(rp) 					:: rD
     ! Debye length
     REAL(rp) 					:: re
     ! Classical electron radius
     REAL(rp) 					:: Gammac_min


     REAL(rp), DIMENSION(2) :: aH=(/274._rp,0._rp/)
     REAL(rp), DIMENSION(7) :: aC=(/144._rp,118._rp,95._rp,70._rp, &
          42._rp,39._rp,0._rp/)
     REAL(rp), DIMENSION(11) :: aNe=(/111._rp,100._rp,90._rp,80._rp, &
          71._rp,62._rp,52._rp,40._rp,24._rp,23._rp,0._rp/)
     REAL(rp), DIMENSION(19) :: aAr=(/96._rp,90._rp,84._rp,78._rp,72._rp, &
          65._rp,59._rp,53._rp,47._rp,44._rp,41._rp,38._rp,25._rp,32._rp, &
          27._rp,21._rp,13._rp,13._rp,0._rp/)


     REAL(rp), DIMENSION(2) :: IH=(/14.9916_rp,huge(1._rp)/)
     REAL(rp), DIMENSION(7) :: IC=(/65.9_rp,92.6_rp,134.8_rp,214.2_rp, &
          486.2_rp,539.5_rp,huge(1._rp)/)
     REAL(rp), DIMENSION(11) :: INe=(/137.2_rp,165.2_rp,196.9_rp,235.2_rp, &
          282.8_rp,352.6_rp,475.0_rp,696.8_rp,1409.2_rp,1498.4_rp,huge(1._rp)/)
     REAL(rp), DIMENSION(19) :: IAr=(/188.5_rp,219.4_rp,253.8_rp,293.4_rp, &
          339.1_rp,394.5_rp,463.4_rp,568.0_rp,728.0_rp,795.9_rp,879.8_rp, &
          989.9_rp,1138.1_rp,1369.5_rp,1791.2_rp,2497.0_rp,4677.2_rp, &
          4838.2_rp,huge(1._rp)/)

     CHARACTER(30) :: neut_prof
     REAL(rp) 			:: Ec,Ec_min
     ! Critical electric field
     LOGICAL  :: LargeCollisions
     
  END TYPE PARAMS_MS

  TYPE, PRIVATE :: PARAMS_SS
     REAL(rp) 			:: Te
     ! Electron temperature
     REAL(rp) 			:: Ti
     ! Ion temperature
     REAL(rp) 			:: ne
     ! Background electron density
     REAL(rp) 			:: Zeff
     ! Effective atomic number of ions
     REAL(rp) 			:: rD
     ! Debye radius
     REAL(rp) 			:: re
     ! Classical electron radius
     REAL(rp) 			:: CoulombLogee,CoulombLogei
     ! Coulomb logarithm
     REAL(rp) 			:: CLog1, CLog2,CLog0_1, CLog0_2
     REAL(rp) 			:: VTe
     ! Thermal velocity of background electrons
     REAL(rp) 			:: VTeo
     REAL(rp) 			:: delta
     ! delta parameter
     REAL(rp) 			:: deltao
     REAL(rp) 			:: Gammac
     ! Collisional Gamma factor
     REAL(rp) 			:: Gammaco
     ! Collisional gamma factor normalized for SDE for dp
     REAL(rp) 			:: Tau
     ! Collisional time of relativistic particles
     REAL(rp) 			:: Tauc
     ! Collisional time of thermal particles
     REAL(rp) 			:: taur
     ! radiation timescale
     REAL(rp) 			:: Ec
     ! Critical electric field
     REAL(rp) 			:: ED
     ! Dreicer electric field
     REAL(rp) 			:: dTau
     ! Subcycling time step in collisional time units (Tau)
     INTEGER(ip)		:: subcycling_iterations,ngrid1
     REAL(rp) :: coll_per_dump_dt,Clog_const
     REAL(rp) :: p_min,p_crit,p_therm,gam_min,gam_crit,gam_therm,pmin_scale
     LOGICAL :: ConserveLA,sample_test,avalanche,energy_diffusion,FP_bremsstrahlung,pitch_diffusion
     CHARACTER(30) :: Clog_model,min_secRE,LAC_gam_resolution
     
     REAL(rp), DIMENSION(3) 	:: x = (/1.0_rp,0.0_rp,0.0_rp/)
     REAL(rp), DIMENSION(3) 	:: y = (/0.0_rp,1.0_rp,0.0_rp/)
     REAL(rp), DIMENSION(3) 	:: z = (/0.0_rp,0.0_rp,1.0_rp/)

     TYPE(PROFILES) 			   :: P

     REAL(rp), DIMENSION(:,:), ALLOCATABLE :: rnd_num
     INTEGER 				   :: rnd_num_count
     INTEGER 				   :: rnd_dim = 40000000_idef
  END TYPE PARAMS_SS

  TYPE(PARAMS_MS), PRIVATE :: cparams_ms
  TYPE(PARAMS_SS), PRIVATE :: cparams_ss

  PUBLIC :: initialize_collision_params,&
       normalize_collisions_params,&
       collision_force,&
       deallocate_collisions_params,&
       save_collision_params,&    
       include_CoulombCollisions_GC_p,&
       include_CoulombCollisionsLA_GC_p,&
       include_CoulombCollisions_FO_p,&
       check_collisions_params,&
       define_collisions_time_step,&
       large_angle_source
  PRIVATE :: load_params_ms,&
       load_params_ss,&
       normalize_params_ms,&
       normalize_params_ss,&
       save_params_ms,&
       save_params_ss,&
       deallocate_params_ms,&
       cross,&
       CA,&
       CB_ee,&
       CB_ei,&
       CB_ei_FIO,&
       CF,&
       CF_FIO,&
       fun,&
       nu_S,&
       nu_S_FIO,&
       nu_par,&
       nu_D,&
       nu_D_FIO,&
       Gammac_wu,&
       CLog_wu,&
       VTe_wu,&
       Gammacee,&
       CLog,&
       VTe,&
       CA_SD,&
       CB_ee_SD,&
       CB_ei_SD,&
       CF_SD,&
       delta,&
       unitVectorsC,&
       unitVectors_p

contains

  ! * * * * * * * * * * * *  * * * * * * * * * * * * * !
  ! * SUBROUTINES FOR INITIALIZING COLLISIONS PARAMS * !
  ! * * * * * * * * * * * *  * * * * * * * * * * * * * !


  subroutine load_params_ms(params)
    TYPE(KORC_PARAMS), INTENT(INOUT) 	:: params
    !REAL(rp) 				:: Te
    ! Background electron temperature in eV
    !REAL(rp) 				:: ne
    ! Background electron density in 1/m^3
    !INTEGER 				:: num_impurity_species
    !REAL(rp), DIMENSION(10) 		:: Zo
    ! Full nuclear charge of each impurity: Z=1 for D, Z=10 for Ne
    !REAL(rp), DIMENSION(10) 		:: Zj
    ! Atomic number of each impurity: Z=1 for D, Z=10 for Ne
    !REAL(rp), DIMENSION(10) 		:: nz
    ! Impurity densities
    !REAL(rp), DIMENSION(10) 		:: IZj
    ! Ionization energy of impurity in eV
    !REAL(rp), DIMENSION(10) 		:: aZj
    INTEGER :: i

    !NAMELIST /CollisionParamsMultipleSpecies/ num_impurity_species,Te,ne, &
    !     Zo,Zj,nz,IZj


    !open(unit=output_unit_write,file=TRIM(params%path_to_inputs), &
    !     status='OLD',form='formatted')
    !read(output_unit_write,nml=CollisionParamsMultipleSpecies)
    !close(output_unit_write)

    if (params%profile_model(10:10).eq.'H') then
       cparams_ms%num_impurity_species = 6
       params%num_impurity_species = 6
    else
       cparams_ms%num_impurity_species = num_impurity_species
       params%num_impurity_species = num_impurity_species
    endif

    
    ALLOCATE(cparams_ms%Zj(cparams_ms%num_impurity_species))
    ALLOCATE(cparams_ms%Zo(cparams_ms%num_impurity_species))
    ALLOCATE(cparams_ms%nz(cparams_ms%num_impurity_species))
    ALLOCATE(cparams_ms%neb(cparams_ms%num_impurity_species))
    ALLOCATE(cparams_ms%IZj(cparams_ms%num_impurity_species))
    ALLOCATE(cparams_ms%aZj(cparams_ms%num_impurity_species))
    ALLOCATE(cparams_ms%Ee_IZj(cparams_ms%num_impurity_species))

    cparams_ms%Te = Te_mult*C_E
    cparams_ms%ne = ne_mult
    cparams_ms%nH = ne_mult

    if  (params%profile_model.eq.'M3D_C1') then
       do i=1,cparams_ms%num_impurity_species
          cparams_ms%Zj(i) = real(i)-1._rp
          cparams_ms%Zo(i) = Zo_mult(1)       
       end do
       cparams_ms%nz(1) = nz_mult(1)

       params%Zj=cparams_ms%Zj
    elseif (params%profile_model(10:10).eq.'H') then
       cparams_ms%Zj(1)=0
       cparams_ms%Zo(1)=18
       cparams_ms%Zj(2)=1
       cparams_ms%Zo(2)=18
       cparams_ms%Zj(3)=2
       cparams_ms%Zo(3)=18
       cparams_ms%Zj(4)=3
       cparams_ms%Zo(4)=18
       cparams_ms%Zj(5)=0
       cparams_ms%Zo(5)=1
       cparams_ms%Zj(6)=1
       cparams_ms%Zo(6)=1

       cparams_ms%nz(1) = nz_mult(1)

       params%Zj=cparams_ms%Zj       
    else
       cparams_ms%Zj = Zj_mult(1:cparams_ms%num_impurity_species)
       cparams_ms%Zo = Zo_mult(1:cparams_ms%num_impurity_species)
       cparams_ms%nz = nz_mult(1:cparams_ms%num_impurity_species)
    endif

    if (.not.(params%profile_model(10:10).eq.'H')) then
       do i=1,cparams_ms%num_impurity_species
          if (int(cparams_ms%Zo(i)).eq.1) then
             cparams_ms%IZj(i) = C_E*cparams_ms%IH(int(cparams_ms%Zj(i)+1))
             cparams_ms%aZj(i) = cparams_ms%aH(int(cparams_ms%Zj(i)+1))
          else if (int(cparams_ms%Zo(i)).eq.6) then
             cparams_ms%IZj(i) = C_E*cparams_ms%IC(int(cparams_ms%Zj(i)+1))
             cparams_ms%aZj(i) = cparams_ms%aC(int(cparams_ms%Zj(i)+1))
          else if (int(cparams_ms%Zo(i)).eq.10) then
             cparams_ms%IZj(i) = C_E*cparams_ms%INe(int(cparams_ms%Zj(i)+1))
             cparams_ms%aZj(i) = cparams_ms%aNe(int(cparams_ms%Zj(i)+1))
          else if (int(cparams_ms%Zo(i)).eq.18) then
             cparams_ms%IZj(i) = C_E*cparams_ms%IAr(int(cparams_ms%Zj(i)+1))
             cparams_ms%aZj(i) = cparams_ms%aAr(int(cparams_ms%Zj(i)+1))
          else
             if (params%mpi_params%rank .EQ. 0) then
                write(output_unit_write,'("Atomic number not defined!")')
             end if
             exit             
          end if
       end do
    else
       cparams_ms%IZj(1) = C_E*cparams_ms%IAr(1)
       cparams_ms%aZj(1) = cparams_ms%aAr(1)
       cparams_ms%IZj(2) = C_E*cparams_ms%IAr(2)
       cparams_ms%aZj(2) = cparams_ms%aAr(2)
       cparams_ms%IZj(3) = C_E*cparams_ms%IAr(3)
       cparams_ms%aZj(3) = cparams_ms%aAr(3)
       cparams_ms%IZj(4) = C_E*cparams_ms%IAr(4)
       cparams_ms%aZj(4) = cparams_ms%aAr(4)
       cparams_ms%IZj(5) = C_E*cparams_ms%IH(1)
       cparams_ms%aZj(5) = cparams_ms%aH(1)
       cparams_ms%IZj(6) = C_E*cparams_ms%IH(2)
       cparams_ms%aZj(6) = cparams_ms%aH(2)
    endif

    cparams_ms%nef = ne_mult + sum(cparams_ms%Zj*cparams_ms%nz)
    cparams_ms%neb = (cparams_ms%Zo-cparams_ms%Zj)*cparams_ms%nz

    cparams_ms%rD = SQRT( C_E0*cparams_ms%Te/(cparams_ms%ne*C_E**2) )
    cparams_ms%re = C_RE
    cparams_ms%Ee_IZj = C_ME*C_C**2/cparams_ms%IZj

    cparams_ms%neut_prof=neut_prof

    cparams_ms%Gammac_min = Gammac_wu(params,cparams_ss%P%n_ne,cparams_ss%Te)
    cparams_ms%LargeCollisions = LargeCollisions
    
    if (params%mpi_params%rank .EQ. 0) then
       write(output_unit_write,'("Number of impurity species: ",I16)')& 
            cparams_ms%num_impurity_species
       do i=1,cparams_ms%num_impurity_species
          if (cparams_ms%Zo(i).eq.1) then
             write(output_unit_write,'("H with charge state: ",I16)') int(cparams_ms%Zj(i))
             write(output_unit_write,'("Mean excitation energy I (eV)",E17.10)') &
                  cparams_ms%IZj(i)/C_E
             write(output_unit_write,'("Effective ion length scale a (a_0)",E17.10)') &
                  cparams_ms%aZj(i)
          else if (cparams_ms%Zo(i).eq.6) then
             write(output_unit_write,'("C with charge state: ",I16)') int(cparams_ms%Zj(i))
             write(output_unit_write,'("Mean excitation energy I (eV)",E17.10)') &
                  cparams_ms%IZj(i)/C_E
             write(output_unit_write,'("Effective ion length scale a (a_0)",E17.10)') &
                  cparams_ms%aZj(i)
          else if (cparams_ms%Zo(i).eq.10) then
             write(output_unit_write,'("Ne with charge state: ",I16)') int(cparams_ms%Zj(i))
             write(output_unit_write,'("Mean excitation energy I (eV)",E17.10)') &
                  cparams_ms%IZj(i)/C_E
             write(output_unit_write,'("Effective ion length scale a (a_0)",E17.10)') &
                  cparams_ms%aZj(i)
          else if (cparams_ms%Zo(i).eq.18) then
             write(output_unit_write,'("Ar with charge state: ",I16)') int(cparams_ms%Zj(i))
             write(output_unit_write,'("Mean excitation energy I (eV)",E17.10)') &
                  cparams_ms%IZj(i)/C_E
             write(output_unit_write,'("Effective ion length scale a (a_0)",E17.10)') &
                  cparams_ms%aZj(i)
          end if
       end do
    end if
    
  end subroutine load_params_ms


  subroutine load_params_ss(params)
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    !REAL(rp) 				:: Te
    ! Electron temperature
    !REAL(rp) 				:: Ti
    ! Ion temperature
    !REAL(rp) 				:: ne
    ! Background electron density
    !REAL(rp) 				:: Zeff
    ! Effective atomic number of ions
    !REAL(rp) 				:: dTau
    ! Subcycling time step in collisional time units (Tau)
    !CHARACTER(MAX_STRING_LENGTH) 	:: ne_profile
    !CHARACTER(MAX_STRING_LENGTH) 	:: Te_profile
    !CHARACTER(MAX_STRING_LENGTH) 	:: Zeff_profile
    !CHARACTER(MAX_STRING_LENGTH) 	:: filename
    !REAL(rp) 				:: radius_profile
    !REAL(rp) 				:: neo
    !REAL(rp) 				:: Teo
    !REAL(rp) 				:: Zeffo
    !REAL(rp) 				:: n_ne
    !REAL(rp) 				:: n_Te
    !REAL(rp) 				:: n_Zeff
    !REAL(rp), DIMENSION(4) 		:: a_ne
    !REAL(rp), DIMENSION(4) 		:: a_Te
    !REAL(rp), DIMENSION(4) 		:: a_Zeff
    !LOGICAL 				:: axisymmetric
    !REAL(rp)  ::  n_REr0
    !REAL(rp)  ::  n_tauion
    !REAL(rp)  ::  n_lamfront,psiN_0
    !REAL(rp)  ::  n_lamback,n_lamshelf,n_shelfdelay,n_tauin,n_tauout,n_shelf

    !NAMELIST /CollisionParamsSingleSpecies/ Te, Ti, ne, Zeff, dTau

    !NAMELIST /plasmaProfiles/ radius_profile,ne_profile,neo,n_ne,a_ne,&
    !     Te_profile,Teo,n_Te,a_Te,n_REr0,n_tauion,n_lamfront,n_lamback, &
    !     Zeff_profile,Zeffo,n_Zeff,a_Zeff,filename,axisymmetric, &
    !     n_lamshelf,n_shelfdelay,n_tauin,n_tauout,n_shelf,psiN_0


    !open(unit=output_unit_write,file=TRIM(params%path_to_inputs), &
    !     status='OLD',form='formatted')
    !read(output_unit_write,nml=CollisionParamsSingleSpecies)
    !close(output_unit_write)

    cparams_ss%Te = Te_sing*C_E
    cparams_ss%Ti = Ti_sing*C_E
    cparams_ss%ne = ne_sing
    cparams_ss%Zeff = Zeff_sing
    cparams_ss%dTau = dTau_sing
    cparams_ss%p_therm = p_therm
    cparams_ss%ConserveLA = ConserveLA
    cparams_ss%sample_test = sample_test
    cparams_ss%Clog_model = Clog_model
    cparams_ss%min_secRE = min_secRE
    cparams_ss%pmin_scale = pmin_scale
    cparams_ss%energy_diffusion = energy_diffusion
    cparams_ss%pitch_diffusion = pitch_diffusion
    cparams_ss%LAC_gam_resolution = LAC_gam_resolution
    cparams_ss%FP_bremsstrahlung = FP_bremsstrahlung
    cparams_ss%ngrid1 = ngrid1
    cparams_ss%Clog_const = Clog_const

    cparams_ss%gam_therm = sqrt(1+p_therm*p_therm)
    cparams_ss%gam_min = cparams_ss%gam_therm
    cparams_ss%p_min = cparams_ss%p_therm
    
    cparams_ss%rD = SQRT(C_E0*cparams_ss%Te/(cparams_ss%ne*C_E**2*(1.0_rp + &
         cparams_ss%Te/cparams_ss%Ti)))

    cparams_ss%re = C_E**2/(4.0_rp*C_PI*C_E0*C_ME*C_C**2)
    cparams_ss%CoulombLogee = CLogee_wu(params,cparams_ss%ne,cparams_ss%Te)
    cparams_ss%CoulombLogei = CLogei_wu(params,cparams_ss%ne,cparams_ss%Te)
    
    cparams_ss%VTe = VTe_wu(cparams_ss%Te)
    cparams_ss%delta = cparams_ss%VTe/C_C
    cparams_ss%Gammaco = C_E**4/(4.0_rp*C_PI*C_E0**2)
    cparams_ss%Gammac = Gammac_wu(params,cparams_ss%ne,cparams_ss%Te)
    
    cparams_ss%Tauc = C_ME**2*cparams_ss%VTe**3/cparams_ss%Gammac
    cparams_ss%Tau = C_ME**2*C_C**3/cparams_ss%Gammac

    cparams_ss%Ec = C_ME*C_C/(C_E*cparams_ss%Tau)
    cparams_ss%ED = cparams_ss%ne*C_E**3*cparams_ss%CoulombLogee/ &
         (4.0_rp*C_PI*C_E0**2*cparams_ss%Te)

    cparams_ss%taur=6*C_PI*C_E0*(C_ME*C_C)**3/(C_E**4*params%cpp%Bo**2)
    
    !	ALLOCATE(cparams_ss%rnd_num(3,cparams_ss%rnd_dim))
    !	call RANDOM_NUMBER(cparams_ss%rnd_num)
    cparams_ss%rnd_num_count = 1_idef

    !open(unit=output_unit_write,file=TRIM(params%path_to_inputs), &
    !     status='OLD',form='formatted')
    !read(output_unit_write,nml=plasmaProfiles)
    !close(output_unit_write)

    cparams_ss%P%a = radius_profile
    cparams_ss%P%ne_profile = TRIM(ne_profile)
    cparams_ss%P%neo = neo
    cparams_ss%P%n_ne = n_ne
    cparams_ss%P%a_ne = a_ne

    cparams_ss%P%Te_profile = TRIM(Te_profile)
    cparams_ss%P%Teo = Teo*C_E
    cparams_ss%P%n_Te = n_Te
    cparams_ss%P%a_Te = a_Te

    cparams_ss%P%Zeff_profile = TRIM(Zeff_profile)
    cparams_ss%P%Zeffo = Zeffo
    cparams_ss%P%n_Zeff = n_Zeff
    cparams_ss%P%a_Zeff = a_Zeff
  end subroutine load_params_ss


  subroutine initialize_collision_params(params,spp,P,F,init)
    TYPE(KORC_PARAMS), INTENT(INOUT) :: params
    TYPE(SPECIES), DIMENSION(:), ALLOCATABLE, INTENT(INOUT)       :: spp
    TYPE(PROFILES), INTENT(INOUT)  :: P
    TYPE(FIELDS), INTENT(IN)                :: F
    LOGICAL, INTENT(IN) :: init
    INTEGER 				                       	:: ii
    REAL(rp) :: p_crit,gam_crit,maxEinterp,minEinterp

    if (params%collisions.or.((TRIM(params%field_model).eq.'M3D_C1'.or. &
         TRIM(params%field_model).eq.'NIMROD').and. &
         params%radiation)) then

       if (params%mpi_params%rank .EQ. 0) then
          write(output_unit_write,'(/,"* * * * * * * INITIALIZING COLLISIONS * * * * * * *")')
       end if

       if (init) then

          SELECT CASE (TRIM(params%collisions_model))
          CASE (MODEL1)
             call load_params_ss(params)

             SELECT CASE(TRIM(params%bound_electron_model))
             CASE ('NO_BOUND')
                call load_params_ms(params)

                cparams_ms%Ec=cparams_ss%Ec
                if (.not.(P%ne_profile(1:6).eq.'RE-EVO')) then
                   cparams_ms%Ec_min=cparams_ms%Ec
                else
                   cparams_ms%Ec_min=cparams_ms%Ec* &
                        cparams_ms%Gammac_min/cparams_ss%Gammac
                endif
                
             CASE('HESSLOW')
                call load_params_ms(params)

                cparams_ms%Ec=cparams_ss%Ec* &
                     (1._rp+sum((cparams_ms%Zo-cparams_ms%Zj)* &
                     cparams_ms%nz)/cparams_ss%ne)
                if (.not.(P%ne_profile(1:6).eq.'RE-EVO')) then
                   cparams_ms%Ec_min=cparams_ms%Ec
                else
                   cparams_ms%Ec_min=cparams_ms%Ec* &
                        cparams_ms%Gammac_min/cparams_ss%Gammac
                end if
                
             CASE('ROSENBLUTH')
                call load_params_ms(params)

                cparams_ms%Ec=cparams_ss%Ec* &
                     (1._rp+sum((cparams_ms%Zo-cparams_ms%Zj)* &
                     cparams_ms%nz)/cparams_ss%ne)
                if (.not.(P%ne_profile(1:6).eq.'RE-EVO')) then
                   cparams_ms%Ec_min=cparams_ms%Ec
                else
                   cparams_ms%Ec_min=cparams_ms%Ec* &
                        cparams_ms%Gammac_min/cparams_ss%Gammac
                end if
                
             CASE DEFAULT
                write(output_unit_write,'("Default case")')
             END SELECT

             do ii=1_idef,params%num_species
                ALLOCATE( spp(ii)%vars%nimp(spp(ii)%ppp, &
                     cparams_ms%num_impurity_species) )
                spp(ii)%vars%nimp = 0.0_rp
             end do

#ifdef FIO
             if (TRIM(params%field_model) .eq. 'M3D_C1') then     
                call initialize_m3d_c1_imp(params,F,P, &
                     cparams_ms%num_impurity_species,.true.)        
             endif
#endif 

          CASE (MODEL2)
             call load_params_ms(params)
          CASE DEFAULT
             write(output_unit_write,'("Default case")')
          END SELECT

       end if

       if (params%LargeCollisions) then

          if (params%mpi_params%rank .EQ. 0) then
             write(output_unit_write,'(/,"* * * * * * * LARGE ANGLE COLLISIONS * * * * * * *")')
          end if

          if (TRIM(params%field_model) .eq. 'ANALYTICAL') then

             !write(6,*) 'Eo',F%Eo
             !write(6,*) 'Ec',cparams_ss%Ec
             !write(6,*) 'Ec_min',cparams_ms%Ec_min
             
             cparams_ss%avalanche=.TRUE.
             if (TRIM(params%collisions_model).eq.'NO_BOUND') then
                if (abs(F%Eo).lt.cparams_ss%Ec) then
                   cparams_ss%avalanche=.FALSE.
                end if
             else
                if (abs(F%Eo).lt.cparams_ms%Ec_min) then
                   cparams_ss%avalanche=.FALSE.
                end if             
             end if
             
             if (cparams_ss%avalanche) then

                if (TRIM(params%collisions_model).eq.'NO_BOUND') then
                   p_crit=1/sqrt(abs(F%Eo)/cparams_ss%Ec-1._rp)
                else
                   p_crit=1/sqrt(abs(F%Eo)/cparams_ms%Ec_min-1._rp)
                end if
             end if
             
          else if ((TRIM(params%field_model) .eq. 'EXTERNAL-PSI')) then
             if (F%ReInterp_2x1t) then
                maxEinterp=maxval(F%E_3D%PHI(:,F%ind_2x1t,:)* &
                     F%FLAG3D(:,F%ind_2x1t,:))

                minEinterp=minval(F%E_3D%PHI(:,F%ind_2x1t,:)* &
                     F%FLAG3D(:,F%ind_2x1t,:))
             else if (F%E_profile.eq.'MST_FSA') then
                maxEinterp=F%E_dyn
             end if

             cparams_ss%avalanche=.TRUE.
             if (TRIM(params%collisions_model).eq.'NO_BOUND') then
                if ((abs(maxEinterp).lt.cparams_ss%Ec).and. &
                     (abs(minEinterp).lt.cparams_ss%Ec)) &
                     cparams_ss%avalanche=.FALSE.
             else
                if ((abs(maxEinterp).lt.cparams_ms%Ec_min).and. &
                     (abs(minEinterp).lt.cparams_ms%Ec_min)) &
                     cparams_ss%avalanche=.FALSE.                
             end if

             !write(6,*) 'maxEinterp',maxEinterp,'minEinterp',minEinterp, &
             !     'E_c',cparams_ms%Ec_min,cparams_ss%avalanche
             
             if (cparams_ss%avalanche) then

                if (abs(maxEinterp).gt.abs(minEinterp)) then
                   if (TRIM(params%collisions_model).eq.'NO_BOUND') then
                      p_crit=1/sqrt(abs(maxEinterp)/cparams_ss%Ec-1._rp)
                   else

                      p_crit=1/sqrt(abs(maxEinterp)/cparams_ms%Ec_min-1._rp)
                   end if
                else
                   if (TRIM(params%collisions_model).eq.'NO_BOUND') then
                      p_crit=1/sqrt(abs(minEinterp)/cparams_ss%Ec-1._rp)
                   else
                      p_crit=1/sqrt(abs(minEinterp)/cparams_ms%Ec_min-1._rp)
                   end if
                end if

             end if
             
          else
             write(6,*) 'Need to set p_crit!'
             call korc_abort(25)
          end if

          if (cparams_ss%avalanche) then

             cparams_ss%p_crit=p_crit
             
             gam_crit=sqrt(1+p_crit*p_crit)

             cparams_ss%gam_crit=gam_crit

             cparams_ss%gam_therm=(gam_crit+1._rp)/2._rp
             cparams_ss%p_therm=sqrt(cparams_ss%gam_therm*cparams_ss%gam_therm-1)

             if(cparams_ss%min_secRE.eq.'THERM') then
                cparams_ss%p_min=cparams_ss%p_therm
                cparams_ss%gam_min=cparams_ss%gam_therm
             else
                cparams_ss%p_min=p_crit
                cparams_ss%gam_min=gam_crit
             end if
             
             !write(6,*) p_crit,gam_crit,cparams_ss%p_therm,cparams_ss%gam_therm,cparams_ss%p_min,cparams_ss%gam_min



             if (params%mpi_params%rank .EQ. 0) then
                write(output_unit_write,*) 'Minimum energy of secondary RE is ',&
                     cparams_ss%min_secRE
                write(output_unit_write,*) 'p_crit/(me*c) is: ',p_crit
                write(output_unit_write,*) 'gam_min is: ',cparams_ss%gam_min
                if(.not.init) then
                   if (TRIM(params%field_model) .eq. 'ANALYTICAL') then
                         write(output_unit_write,*) 'Maximum E_PHI : ',F%Eo*params%cpp%Eo,'V/m'
                   else if ((TRIM(params%field_model) .eq. 'EXTERNAL-PSI') &
                        .AND.(F%ReInterp_2x1t)) then
                      if (abs(maxEinterp).gt.abs(minEinterp)) then
                         write(output_unit_write,*) 'Maximum E_PHI : ',maxEinterp*params%cpp%Eo,'V/m'
                      else
                         write(output_unit_write,*) 'Maximum E_PHI : ',minEinterp*params%cpp%Eo,'V/m'
                      end if
                   endif

                   if (TRIM(params%collisions_model).eq.'NO_BOUND') then
                      write(output_unit_write,*) 'E_CH is: ',cparams_ss%Ec*params%cpp%Eo,'V/m'
                   else
                      write(output_unit_write,*) 'E_CH is: ',cparams_ms%Ec_min*params%cpp%Eo,'V/m'
                   end if
                   write(output_unit_write,*) 'tau_c,rel is: ',cparams_ss%Tau*params%cpp%time,'s'
                else
                   if (TRIM(params%field_model) .eq. 'ANALYTICAL') then
                      write(output_unit_write,*) 'Maximum E_PHI : ',F%Eo,'V/m'
                   else if ((TRIM(params%field_model) .eq. 'EXTERNAL-PSI') &
                        .AND.(F%ReInterp_2x1t)) then
                      if (abs(maxEinterp).gt.abs(minEinterp)) then
                         write(output_unit_write,*) 'Maximum E_PHI : ',maxEinterp,'V/m'
                      else
                         write(output_unit_write,*) 'Maximum E_PHI : ',minEinterp,'V/m'
                      end if
                   end if

                   if (TRIM(params%collisions_model).eq.'NO_BOUND') then
                      write(output_unit_write,*) 'E_CH is: ',cparams_ss%Ec,'V/m'
                   else
                      write(output_unit_write,*) 'E_CH is: ',cparams_ms%Ec_min,'V/m'
                   end if
                   write(output_unit_write,*) 'tau_c,rel is: ',cparams_ss%Tau,'s'
                end if                
                write(output_unit_write,'("* * * * * * * * * * * * * * * * * * * * * * * * * *",/)')
             end if

          else

             if (params%mpi_params%rank .EQ. 0) then
                if(.not.init) then
                   if (TRIM(params%field_model) .eq. 'ANALYTICAL') then
                      write(output_unit_write,*) 'Maximum E_PHI : ',F%Eo*params%cpp%Eo,'V/m'
                   else if ((TRIM(params%field_model) .eq. 'EXTERNAL-PSI') &
                        .AND.(F%ReInterp_2x1t)) then
                      if (abs(maxEinterp).gt.abs(minEinterp)) then
                         write(output_unit_write,*) 'Maximum E_PHI : ',maxEinterp*params%cpp%Eo,'V/m'
                      else
                         write(output_unit_write,*) 'Maximum E_PHI : ',minEinterp*params%cpp%Eo,'V/m'
                      end if
                   end if

                   if (TRIM(params%collisions_model).eq.'NO_BOUND') then
                      write(output_unit_write,*) 'E_CH is: ',cparams_ss%Ec*params%cpp%Eo,'V/m'
                   else
                      write(output_unit_write,*) 'E_CH is: ',cparams_ms%Ec_min*params%cpp%Eo,'V/m'
                   end if
                   
                else
                   if (TRIM(params%field_model) .eq. 'ANALYTICAL') then
                      write(output_unit_write,*) 'Maximum E_PHI : ',F%Eo,'V/m'
                   else if ((TRIM(params%field_model) .eq. 'EXTERNAL-PSI') &
                        .AND.(F%ReInterp_2x1t)) then
                      if (abs(maxEinterp).gt.abs(minEinterp)) then
                         write(output_unit_write,*) 'Maximum E_PHI : ',maxEinterp,'V/m'
                      else
                         write(output_unit_write,*) 'Maximum E_PHI : ',minEinterp,'V/m'
                      end if
                   end if

                   if (TRIM(params%collisions_model).eq.'NO_BOUND') then
                         write(output_unit_write,*) 'E_CH is: ',cparams_ss%Ec,'V/m'
                   else
                      write(output_unit_write,*) 'E_CH is: ',cparams_ms%Ec_min,'V/m'
                   end if
                end if
                write(output_unit_write,*) 'No secondary REs will be calculated in this interval'
                write(output_unit_write,*) 'p_min from initial or last time interval used'
                write(output_unit_write,*) 'to calculate collision time scales'
                
                write(output_unit_write,'("* * * * * * * * * * * * * * * * * * * * * * * * * *",/)')
             end if
             
          end if

       end if

       ! for passing minimum gamma to Hollmann sampling routines
       params%gam_min=sqrt(1+cparams_ss%p_min*cparams_ss%p_min* &
            cparams_ss%pmin_scale*cparams_ss%pmin_scale)

       !write(6,*) params%gam_min
       
       if (params%mpi_params%rank .EQ. 0) then
          write(output_unit_write,'("* * * * * * * * * * * * * * * * * * * * * * * * * *",/)')
       end if
       
    end if

    
  end subroutine initialize_collision_params


  subroutine normalize_params_ms(params)
    TYPE(KORC_PARAMS), INTENT(IN) :: params

    cparams_ms%Te = cparams_ms%Te/params%cpp%temperature
    cparams_ms%ne = cparams_ms%ne/params%cpp%density
    cparams_ms%nH = cparams_ms%nH/params%cpp%density
    cparams_ms%nef = cparams_ms%nef/params%cpp%density
    cparams_ms%neb = cparams_ms%neb/params%cpp%density
    if (ALLOCATED(cparams_ms%nz)) cparams_ms%nz = cparams_ms%nz/ &
         params%cpp%density
    if (ALLOCATED(cparams_ms%IZj)) cparams_ms%IZj = cparams_ms%IZj/ &
         params%cpp%energy
    cparams_ms%rD = cparams_ms%rD/params%cpp%length
    cparams_ms%re = cparams_ms%re/params%cpp%length
    cparams_ms%Ec = cparams_ms%Ec/params%cpp%Eo
    cparams_ms%Ec_min = cparams_ms%Ec_min/params%cpp%Eo
    cparams_ms%Gammac_min = cparams_ms%Gammac_min*params%cpp%time/ &
         (params%cpp%mass**2*params%cpp%velocity**3)
  end subroutine normalize_params_ms


  subroutine normalize_params_ss(params)
    !! Calculate constant quantities used in various functions within
    !! this module
    TYPE(KORC_PARAMS), INTENT(IN) :: params

    cparams_ss%Clog1 = -1.15_rp*LOG10(1.0E-6_rp*params%cpp%density)
    cparams_ss%Clog2 = 2.3_rp*LOG10(params%cpp%temperature/C_E)
    cparams_ss%Clog0_1 = -LOG(1.0E-20_rp*params%cpp%density)/2._rp
    cparams_ss%Clog0_2 = LOG(1.0E-3 *params%cpp%temperature/C_E)
    cparams_ss%Gammaco = cparams_ss%Gammaco*params%cpp%density* &
         params%cpp%time/(params%cpp%mass**2*params%cpp%velocity**3)
    cparams_ss%VTeo = SQRT(params%cpp%temperature/C_ME)/params%cpp%velocity
    cparams_ss%deltao = params%cpp%velocity/C_C

    cparams_ss%Te = cparams_ss%Te/params%cpp%temperature
    cparams_ss%Ti = cparams_ss%Ti/params%cpp%temperature
    cparams_ss%ne = cparams_ss%ne/params%cpp%density
    cparams_ss%rD = cparams_ss%rD/params%cpp%length
    cparams_ss%re = cparams_ss%re/params%cpp%length
    cparams_ss%VTe = cparams_ss%VTe/params%cpp%velocity
    cparams_ss%Gammac = cparams_ss%Gammac*params%cpp%time/ &
         (params%cpp%mass**2*params%cpp%velocity**3)
    cparams_ss%Tau = cparams_ss%Tau/params%cpp%time
    cparams_ss%Tauc = cparams_ss%Tauc/params%cpp%time
    cparams_ss%Ec = cparams_ss%Ec/params%cpp%Eo
    cparams_ss%ED = cparams_ss%ED/params%cpp%Eo

    cparams_ss%taur=cparams_ss%taur/params%cpp%time
    
    cparams_ss%P%a = cparams_ss%P%a/params%cpp%length
    cparams_ss%P%neo = cparams_ss%P%neo/params%cpp%density
    cparams_ss%P%n_ne = cparams_ss%P%n_ne/params%cpp%density
    cparams_ss%P%Teo = cparams_ss%P%Teo/params%cpp%temperature
  end subroutine normalize_params_ss


  subroutine normalize_collisions_params(params)
    TYPE(KORC_PARAMS), INTENT(IN) :: params

    if (params%collisions) then
       SELECT CASE (TRIM(params%collisions_model))
       CASE (MODEL1)
          call normalize_params_ss(params)

          SELECT CASE(TRIM(params%bound_electron_model))
          CASE ('NO_BOUND')
             call normalize_params_ms(params)
          CASE('HESSLOW')
             call normalize_params_ms(params)
          CASE('ROSENBLUTH')
             call normalize_params_ms(params)
          CASE DEFAULT
             write(output_unit_write,'("Default case")')
          END SELECT
             
       CASE (MODEL2)
          call normalize_params_ms(params)
       CASE DEFAULT
          write(output_unit_write,'("Default case")')
       END SELECT
    end if
  end subroutine normalize_collisions_params


  subroutine collision_force(spp,U,Fcoll)
    !! For multiple-species collisions
    !! J. R. Martin-Solis et al. PoP 22, 092512 (2015)
    !! if (params%collisions .AND. (TRIM(params%collisions_model) .EQ.
    !! 'MULTIPLE_SPECIES')) then call collision_force(spp(ii),U_os,Fcoll)
    !!	U_RC = U_RC + a*Fcoll/spp(ii)%q end if

    TYPE(SPECIES), INTENT(IN) 		:: spp
    REAL(rp), DIMENSION(3), INTENT(IN) 	:: U
    REAL(rp), DIMENSION(3), INTENT(OUT) :: Fcoll
    REAL(rp), DIMENSION(3) 		:: V
    REAL(rp), DIMENSION(3) 		:: Fcolle
    REAL(rp), DIMENSION(3) 		:: Fcolli
    REAL(rp) 				:: gamma
    REAL(rp) 				:: tmp
    REAL(rp) 				:: ae
    REAL(rp) 				:: ai
    REAL(rp) 				:: Clog_ef
    REAL(rp) 				:: Clog_eb
    REAL(rp) 				:: Clog_eH
    REAL(rp) 				:: Clog_eZj
    REAL(rp) 				:: Clog_eZo
    INTEGER 				:: ppi

    gamma = SQRT(1.0_rp + DOT_PRODUCT(U,U))
    V = U/gamma

    tmp = (gamma - 1.0_rp)*SQRT(gamma + 1.0_rp)
    Clog_ef = log(0.5_rp*tmp*(cparams_ms%rD/cparams_ms%re)/gamma)
    ae = cparams_ms%nef*Clog_ef
    do ppi=1_idef,cparams_ms%num_impurity_species
       Clog_eb = log(tmp*cparams_ms%Ee_IZj(ppi))
       ae = ae + cparams_ms%neb(ppi)*Clog_eb
    end do

    tmp = (gamma**2 - 1.0_rp)/gamma
    Clog_eH = log( tmp*(cparams_ms%rD/cparams_ms%re) )
    ai = cparams_ms%nH*Clog_eH
    do ppi=1_idef,cparams_ms%num_impurity_species
       Clog_eZj = log( cparams_ms%rD/(cparams_ms%Zj(ppi)* &
            cparams_ms%re*cparams_ms%Ee_IZj(ppi)) )
       Clog_eZo = log(tmp*cparams_ms%Ee_IZj(ppi))
       ai = ai + &
            cparams_ms%nz(ppi)*(Clog_eZj*cparams_ms%Zj(ppi)**2 + &
            Clog_eZo*cparams_ms%Zo(ppi)**2)
    end do

    tmp = gamma*(gamma + 1.0_rp)/(SQRT(DOT_PRODUCT(U,U))**3)
    Fcolle = -4.0_rp*C_PI*ae*spp%m*(cparams_ms%re**2)*tmp*U

    tmp = gamma/(SQRT(DOT_PRODUCT(U,U))**3)
    Fcolli = -4.0_rp*C_PI*ai*spp%m*(cparams_ms%re**2)*tmp*U

    Fcoll = Fcolle + Fcolli
  end subroutine collision_force


  subroutine define_collisions_time_step(params,F,init)
    TYPE(KORC_PARAMS), INTENT(INOUT) 	:: params
    TYPE(FIELDS), INTENT(IN) :: F
    LOGICAL, INTENT(IN)  :: init
    INTEGER(ip) 			:: iterations
    REAL(rp) 				:: E,E_min
    REAL(rp) 				:: v
    REAL(rp) 				:: Tau
    REAL(rp), DIMENSION(3) 		:: nu
    REAL(rp) 				:: num_collisions_in_simulation


    if (params%collisions) then
       E = C_ME*C_C**2 + params%minimum_particle_energy*params%cpp%energy

       
       E_min=sqrt((cparams_ss%p_min*cparams_ss%pmin_scale* &
            params%cpp%mass*params%cpp%velocity* &
            C_C)**2+(C_ME*C_C**2)**2)

       !write(6,'("E_min (MeV)",E17.10)') E/(10**6*C_E)
       !write(6,'("E_min (MeV)",E17.10)') E_min/(10**6*C_E)

       if (.not.params%LargeCollisions) then
          v = SQRT(1.0_rp - (C_ME*C_C**2/E)**2)
          !write(6,*) 'v_min',v
       else
          v = SQRT(1.0_rp - (C_ME*C_C**2/E_min)**2)
          !write(6,*) 'v_therm',v
       end if


       
       if ((params%profile_model.eq.'M3D_C1').or. &
            (params%profile_model(10:10).eq.'H')) then
          nu = (/nu_S_FIO(params,v),nu_D_FIO(params,v),nu_par(v)/)
       else
          nu = (/nu_S(params,v),nu_D(params,v),nu_par(v)/)
       endif
       Tau = MINVAL( 1.0_rp/nu )

       
       !write(output_unit_write,'("collision freqencies ",F25.12)') nu(3)
       !write(6,*) 'collision times',1/nu*params%cpp%time
       !write(6,*) 'p_min',cparams_ss%p_min
       
       cparams_ss%subcycling_iterations = ceiling(cparams_ss%dTau*Tau/ &
            params%dt,ip)
       params%coll_cadence=cparams_ss%subcycling_iterations

       if (params%LargeCollisions.and.params%snapshot_frequency.gt.0._rp) then

          !write(6,*) 'params%snapshot_frequency',params%snapshot_frequency*params%cpp%time
          !write(6,*) 'cparams_ss%dTau*Tau',cparams_ss%dTau*Tau*params%cpp%time
          !write(6,*) 'FLOOR(params%snapshot_frequency/cparams_ss%dTau*Tau)', &
          !     FLOOR(params%snapshot_frequency/ &
          !     (cparams_ss%dTau*Tau),ip)
          
          params%coll_per_dump=ceiling(params%snapshot_frequency/ &
               (cparams_ss%dTau*Tau))

          cparams_ss%coll_per_dump_dt=params%snapshot_frequency/params%coll_per_dump

          params%coll_per_dump_dt=cparams_ss%coll_per_dump_dt

          if (params%coll_per_dump.gt.params%t_skip) then
             write(6,*) 'more collisional iterations than orbit iterations, decrease orbit timestep!'
             call korc_abort(26)
          endif
          
          params%orbits_per_coll=ceiling(cparams_ss%coll_per_dump_dt/ &
               params%dt)

          params%dt=cparams_ss%coll_per_dump_dt/float(params%orbits_per_coll)         
          
       end if
       
       if (init) num_collisions_in_simulation = params%simulation_time/Tau

       if (params%mpi_params%rank .EQ. 0) then
          write(output_unit_write,'("* * * * * * * * * * * SUBCYCLING FOR  &
               COLLISIONS * * * * * * * * * * *")')

         write(output_unit_write,'("Slowing down freqency (CF): ",E17.10)') &
               nu(1)/params%cpp%time
          write(output_unit_write,'("Pitch angle scattering freqency (CB): ",E17.10)') &
               nu(2)/params%cpp%time
          write(output_unit_write,'("Speed diffusion freqency (CA): ",E17.10)') &
               nu(3)/params%cpp%time

!          write(6,*) Tau
          
          write(output_unit_write,'("The shorter collisional time in the simulations  &
               is: ",E17.10," s")') Tau*params%cpp%time
          write(output_unit_write,'("Number of KORC iterations per collision: ",I16)')  &
               cparams_ss%subcycling_iterations
          if (init) then
             write(output_unit_write,'("Number of collisions in simulated time: ",E17.10)')  &
                  num_collisions_in_simulation
          end if

          if (params%LargeCollisions) then

             write(output_unit_write,'("Number of collision steps per dump step: ",I16)') params%coll_per_dump

             write(output_unit_write,'("Collision time step: ",E17.10)') params%coll_per_dump_dt*params%cpp%time

             write(output_unit_write,'("Number of orbit steps per collision step: ",I16)') params%orbits_per_coll

             write(output_unit_write,'("Orbit time step: ",E17.10)') params%dt*params%cpp%time
             
          end if
          
          
          write(output_unit_write,'("* * * * * * * * * * * * * * * * * * * * &
               * * * * * * * * * * * * * * *",/)')
       end if
    end if
  end subroutine define_collisions_time_step


  ! * * * * * * * * * * * *  * * * * * * * * * * * * * * * * * * * !
  ! * FUNCTIONS OF COLLISION OPERATOR FOR SINGLE-SPECIES PLASMAS * !
  ! * * * * * * * * * * * *  * * * * * * * * * * * * * * * * * * * !

  ! *_wu functions have physical units!
  
  function VTe_wu(Te)
    REAL(rp), INTENT(IN) 	:: Te
    !! In Joules
    REAL(rp) 			:: VTe_wu

    VTe_wu = SQRT(2.0_rp*Te/C_ME)
  end function VTe_wu


  function VTe(Te)
    !! Dimensionless temperature
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp) 				:: VTe

    VTe = SQRT(2.0_rp*Te)*cparams_ss%VTeo
  end function VTe


  function Gammac_wu(params,ne,Te)
    !! With units
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te ! In Joules
    REAL(rp) 				:: Gammac_wu

    Gammac_wu = ne*CLogee_wu(params,ne,Te)*cparams_ss%Gammaco
  end function Gammac_wu


  function Gammacee(v,ne,Te)
    !! Dimensionless ne and Te
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp) 				:: Gammacee

    Gammacee = ne*CLogee(v,ne,Te)*cparams_ss%Gammaco
  end function Gammacee

  function CLog_wu(ne,Te)
    !! With units
    REAL(rp), INTENT(IN) 	:: ne
    !! ne is in m^-3 and below is converted to cm^-3
    REAL(rp), INTENT(IN) 	:: Te ! In Joules
    REAL(rp) 				:: CLog_wu

    CLog_wu = 25.3_rp - 1.15_rp*LOG10(1E-6_rp*ne) + 2.3_rp*LOG10(Te/C_E)
    
  end function CLog_wu

  function CLog0_wu(ne,Te)
    !! With units
    REAL(rp), INTENT(IN) 	:: ne
    !! ne is in m^-3 and below is converted to cm^-3
    REAL(rp), INTENT(IN) 	:: Te ! In Joules
    REAL(rp) 				:: CLog0_wu

    CLog0_wu = 14.9_rp - LOG(1E-20_rp*ne)/2._rp + LOG(1E-3_rp*Te/C_E)
    
  end function CLog0_wu

  function CLogee_wu(params,ne,Te)
    
    !! With units
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: ne
    !! ne is in m^-3 and below is converted to cm^-3
    REAL(rp), INTENT(IN) 	:: Te ! In Joules
    REAL(rp) 				:: CLogee_wu
    REAL(rp)  :: k=5._rp

    if (cparams_ss%Clog_model.eq.'HESSLOW') then
       CLogee_wu = CLog0_wu(ne,Te)+ &
            log(1+(2*(params%minimum_particle_g-1)/ &
            (VTe_wu(Te)/C_C)**2)**(k/2._rp))/k

    else if (cparams_ss%Clog_model.eq.'CONSTANT') then
       CLogee_wu = cparams_ss%Clog_const

    else if (cparams_ss%Clog_model.eq.'MCDEVITT') then
       CLogee_wu = CLog0_wu(ne,Te)+ &
            log(1+(2*(params%minimum_particle_g-1)/ &
            (VTe_wu(Te)/C_C)**2)**(k/2._rp))/k
    end if
       
  end function CLogee_wu

  function CLogei_wu(params,ne,Te)
    
    !! With units
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: ne
    !! ne is in m^-3 and below is converted to cm^-3
    REAL(rp), INTENT(IN) 	:: Te ! In Joules
    REAL(rp) 				:: CLogei_wu
    REAL(rp)  :: k=5._rp
    REAL(rp)  :: p

    p=sqrt(params%minimum_particle_g**2-1)

    if (cparams_ss%Clog_model.eq.'CONSTANT') then
       CLogei_wu = cparams_ss%Clog_const
    else
       CLogei_wu = CLog0_wu(ne,Te)+ &
            log(1+(2*p/(VTe_wu(Te)/C_C))**k)/k
    end if
  end function CLogei_wu
  
  function CLog(ne,Te) ! Dimensionless ne and Te
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp) 				:: CLog

    CLog = 25.3_rp - 1.15_rp*LOG10(ne) + 2.3_rp*LOG10(Te) + &
         cparams_ss%CLog1 + cparams_ss%CLog2
  end function CLog

  function CLog0(ne,Te) ! Dimensionless ne and Te
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp) 				:: CLog0

    CLog0 = 14.9_rp - LOG(ne)/2._rp + LOG(Te) + &
         cparams_ss%CLog0_1 + cparams_ss%CLog0_2
  end function CLog0
  
  function CLogee(v,ne,Te)
    
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp), INTENT(IN) 	:: ne
    !! ne is in m^-3 and below is converted to cm^-3
    REAL(rp), INTENT(IN) 	:: Te ! In Joules
    REAL(rp) 				:: CLogee
    REAL(rp)  :: k=5._rp
    REAL(rp)  :: gam
    REAL(rp) :: gam_min

    gam=1/sqrt(1-v**2)
    gam_min=cparams_ss%gam_min
    
    if (cparams_ss%Clog_model.eq.'HESSLOW') then
       CLogee = CLog0(ne,Te)+ &
            log(1+(2*(gam-1)/VTe(Te)**2)**(k/2._rp))/k
       
    else if (cparams_ss%Clog_model.eq.'CONSTANT') then
       CLogee = cparams_ss%Clog_const
       
    else if (cparams_ss%Clog_model.eq.'MCDEVITT') then
       CLogee = CLog0(ne,Te)+ &
            log(1+(2*(gam-1)/VTe(Te)**2)**(k/2._rp))/k+ &
            log(sqrt(2*(gam_min-1._rp)/(gam-1._rp)))
    end if

!    write(output_unit_write,*) gam,CLogee
  end function CLogee

  function CLogei(v,ne,Te)
    
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp), INTENT(IN) 	:: ne
    !! ne is in m^-3 and below is converted to cm^-3
    REAL(rp), INTENT(IN) 	:: Te ! In Joules
    REAL(rp) 				:: CLogei
    REAL(rp)  :: k=5._rp
    REAL(rp)  :: gam,p

    gam=1/sqrt(1-v**2)
    p=gam*v

    if (cparams_ss%Clog_model.eq.'CONSTANT') then
       CLogei = cparams_ss%Clog_const
    else       
       CLogei = CLog0(ne,Te)+log(1+(2*p/VTe(Te))**k)/k
    end if
       
  end function CLogei
  
  function delta(Te)
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp) 				:: delta

    delta = VTe(Te)*cparams_ss%deltao
  end function delta


  function psi(x)
    REAL(rp), INTENT(IN) 	:: x
    REAL(rp) 				:: psi

    psi = 0.5_rp*(ERF(x) - 2.0_rp*x*EXP(-x**2)/SQRT(C_PI))/x**2
  end function psi


  function CA(v)
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp) 				:: CA
    REAL(rp) 				:: x

    x = v/cparams_ss%VTe

    if ((.not.cparams_ms%LargeCollisions).or. &
         (.not.(cparams_ss%P%ne_profile(1:6).eq.'RE-EVO'))) then
       CA  = cparams_ss%Gammac*psi(x)/v
    else
       CA  = cparams_ms%Gammac_min*psi(x)/v
    endif
  end function CA

  function CA_SD(v,ne,Te)
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp) 				:: CA_SD
    REAL(rp) 				:: x

 !   write(6,*) ne,Te
    
    x = v/VTe(Te)
    CA_SD  = Gammacee(v,ne,Te)*psi(x)/v

!    write(output_unit_write,'("ne, "E17.10)') ne
!    write(output_unit_write,'("Te, "E17.10)') Te
    
!    write(output_unit_write,'("x, "E17.10)') x
!    write(output_unit_write,'("psi, "E17.10)') psi(x)
!    write(output_unit_write,'("Gammac, "E17.10)') Gammac(ne,Te)
    
  end function CA_SD
  
  function dCA_SD(v,me,ne,Te)
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp), INTENT(IN) 	:: me
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp) 				:: dCA_SD
    REAL(rp) 				:: x
    real(rp)  :: gam

    gam=1/sqrt(1-v**2)
    x = v/VTe(Te)
    dCA_SD  = Gammacee(v,ne,Te)*((2*(gam*v)**2-1)*psi(x)+ &
         2.0_rp*x*EXP(-x**2)/SQRT(C_PI))/(gam**3*me*v**2)
  end function dCA_SD

  function CF(params,v)
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp) 				:: CF
    REAL(rp) 				:: CF_temp
    REAL(rp) 				:: x
    INTEGER :: i
    REAL(rp)  :: k=5._rp

    x = v/cparams_ss%VTe

    if ((.not.cparams_ms%LargeCollisions).or. &
         (.not.(cparams_ss%P%ne_profile(1:6).eq.'RE-EVO'))) then
       CF  = cparams_ss%Gammac*psi(x)/cparams_ss%Te
    else
       CF  = cparams_ms%Gammac_min*psi(x)/cparams_ss%Te
    endif

    if (params%bound_electron_model.eq.'HESSLOW') then
       CF_temp=CF
       do i=1,cparams_ms%num_impurity_species
          if ((.not.cparams_ms%LargeCollisions).or. &
               (.not.(cparams_ss%P%ne_profile(1:6).eq.'RE-EVO'))) then
             CF_temp=CF_temp+CF*cparams_ms%nz(i)/cparams_ms%ne* &
                  (cparams_ms%Zo(i)-cparams_ms%Zj(i))/ &
                  CLogee(v,cparams_ss%ne,cparams_ss%Te)* &
                  (log(1+h_j(i,v)**k)/k-v**2)
          else
             CF_temp=CF_temp+CF*cparams_ms%nz(i)/cparams_ss%P%n_ne* &
                  (cparams_ms%Zo(i)-cparams_ms%Zj(i))/ &
                  CLogee(v,cparams_ss%P%n_ne,cparams_ss%Te)* &
                  (log(1+h_j(i,v)**k)/k-v**2)
          end if
       end do
       CF=CF_temp
       
    else if (params%bound_electron_model.eq.'ROSENBLUTH') then
       CF_temp=CF
       do i=1,cparams_ms%num_impurity_species
          CF_temp=CF_temp+CF*cparams_ms%nz(i)/cparams_ms%ne* &
               (cparams_ms%Zo(i)-cparams_ms%Zj(i))/2._rp
       end do
       CF=CF_temp
       
    end if
    
  end function CF
  
  function CF_FIO(params,v)
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp) 				:: CF_FIO
    REAL(rp) 				:: CF_temp
    REAL(rp) 				:: x
    INTEGER :: i
    REAL(rp)  :: k=5._rp

    x = v/cparams_ss%VTe
    CF_FIO  = cparams_ss%Gammac*psi(x)/cparams_ss%Te

    if (params%bound_electron_model.eq.'HESSLOW') then
       CF_temp=CF_FIO
       do i=1,1
          CF_temp=CF_temp+CF_FIO*cparams_ms%nz(i)/cparams_ms%ne* &
               (cparams_ms%Zo(i)-cparams_ms%Zj(i))/ &
               CLogee(v,cparams_ss%ne,cparams_ss%Te)* &
               (log(1+h_j(i,v)**k)/k-v**2) 
       end do
       CF_FIO=CF_temp
       
    end if
    
  end function CF_FIO

  function CF_SD(params,v,ne,Te)
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp) 				:: CF_SD
    REAL(rp) 				:: CF_temp
    REAL(rp) 				:: x
    INTEGER :: i
    REAL(rp)  :: k=5._rp

    x = v/VTe(Te)
    CF_SD  = Gammacee(v,ne,Te)*psi(x)/Te

    if (params%bound_electron_model.eq.'HESSLOW') then
       CF_temp=CF_SD
       if ((cparams_ms%Zj(1).eq.0.0).and. &
            (neut_prof.eq.'UNIFORM')) then
          CF_temp=CF_temp+CF_SD*cparams_ms%nz(1)/ne* &
               (cparams_ms%Zo(1)-cparams_ms%Zj(1))/ &
               CLogee(v,ne,Te)*(log(1+h_j(1,v)**k)/k-v**2)
       else if ((cparams_ms%Zj(1).eq.0.0).and. &
            (neut_prof.eq.'HOLLOW')) then
          CF_temp=CF_temp+CF_SD*max(cparams_ms%nz(1)-ne,0._rp)/ne* &
               (cparams_ms%Zo(1)-cparams_ms%Zj(1))/ &
               CLogee(v,ne,Te)*(log(1+h_j(1,v)**k)/k-v**2) 
       else
          CF_temp=CF_temp+CF_SD*cparams_ms%nz(1)/cparams_ms%ne* &
               (cparams_ms%Zo(1)-cparams_ms%Zj(1))/ &
               CLogee(v,ne,Te)*(log(1+h_j(1,v)**k)/k-v**2) 
       endif
       
       do i=2,cparams_ms%num_impurity_species
          CF_temp=CF_temp+CF_SD*cparams_ms%nz(i)/cparams_ms%ne* &
               (cparams_ms%Zo(i)-cparams_ms%Zj(i))/ &
               CLogee(v,ne,Te)*(log(1+h_j(i,v)**k)/k-v**2) 
       end do
       CF_SD=CF_temp
       
    else if (params%bound_electron_model.eq.'ROSENBLUTH') then
       CF_temp=CF_SD
       do i=1,cparams_ms%num_impurity_species
          CF_temp=CF_temp+CF_SD*cparams_ms%nz(i)/cparams_ms%ne* &
               (cparams_ms%Zo(i)-cparams_ms%Zj(i))/2._rp
       end do
       CF_SD=CF_temp
       
    end if
    
  end function CF_SD
  
  function CF_SD_FIO(params,v,ne,Te,nimp)
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp),DIMENSION(cparams_ms%num_impurity_species), INTENT(IN) 	:: nimp
    REAL(rp) 				:: CF_SD_FIO
    REAL(rp) 				:: CF_temp
    REAL(rp) 				:: x
    INTEGER :: i
    REAL(rp)  :: k=5._rp

    x = v/VTe(Te)
    CF_SD_FIO  = Gammacee(v,ne,Te)*psi(x)/Te

    if (params%bound_electron_model.eq.'HESSLOW') then
       CF_temp=CF_SD_FIO
       do i=1,cparams_ms%num_impurity_species
          CF_temp=CF_temp+CF_SD_FIO*nimp(i)/ne* &
               (cparams_ms%Zo(i)-cparams_ms%Zj(i))/ &
               CLogee(v,ne,Te)*(log(1+h_j(i,v)**k)/k-v**2) 
       end do
       CF_SD_FIO=CF_temp
    end if
    
  end function CF_SD_FIO

  function CB_ee(v)
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp) 				:: CB_ee
    REAL(rp) 				:: x

    x = v/cparams_ss%VTe

    if ((.not.cparams_ms%LargeCollisions).or. &
         (.not.(cparams_ss%P%ne_profile(1:6).eq.'RE-EVO'))) then
       CB_ee  = (0.5_rp*cparams_ss%Gammac/v)*(ERF(x) - &
            psi(x) + 0.5_rp*cparams_ss%delta**4*x**2 )
    else
       CB_ee  = (0.5_rp*cparams_ms%Gammac_min/v)*(ERF(x) - &
            psi(x) + 0.5_rp*cparams_ss%delta**4*x**2 )
    endif
    

  end function CB_ee

  function CB_ei(params,v)
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp) 				:: CB_ei
    REAL(rp) 				:: CB_ei_temp
    REAL(rp) 				:: x
    INTEGER :: i

    x = v/cparams_ss%VTe
    if ((.not.cparams_ms%LargeCollisions).or. &
         (.not.(cparams_ss%P%ne_profile(1:6).eq.'RE-EVO'))) then
       CB_ei  = (0.5_rp*cparams_ss%Gammac/v)*(cparams_ss%Zeff* &
            CLogei(v,cparams_ss%ne,cparams_ss%Te)/ &
            CLogee(v,cparams_ss%ne,cparams_ss%Te))
    else
       CB_ei  = (0.5_rp*cparams_ms%Gammac_min/v)*(cparams_ss%Zeff* &
            CLogei(v,cparams_ss%P%n_ne,cparams_ss%Te)/ &
            CLogee(v,cparams_ss%P%n_ne,cparams_ss%Te))
    end if


    if (params%bound_electron_model.eq.'HESSLOW') then
       CB_ei_temp=CB_ei
       do i=1,cparams_ms%num_impurity_species
          if ((.not.cparams_ms%LargeCollisions).or. &
               (.not.(cparams_ss%P%ne_profile(1:6).eq.'RE-EVO'))) then
             CB_ei_temp=CB_ei_temp+CB_ei*cparams_ms%nz(i)/(cparams_ms%ne* &
                  cparams_ss%Zeff*CLogei(v,cparams_ss%ne,cparams_ss%Te))* &
                  g_j(i,v)
          else
             CB_ei_temp=CB_ei_temp+CB_ei*cparams_ms%nz(i)/(cparams_ms%ne* &
                  cparams_ss%Zeff*CLogei(v,cparams_ss%P%n_ne,cparams_ss%Te))* &
                  g_j(i,v)
          end if
       end do
       CB_ei=CB_ei_temp
       
    else if (params%bound_electron_model.eq.'ROSENBLUTH') then
       CB_ei_temp=CB_ei
       do i=1,cparams_ms%num_impurity_species
          CB_ei_temp=CB_ei_temp+CB_ei*cparams_ms%nz(i)/cparams_ms%ne* &
               (cparams_ms%Zo(i)-cparams_ms%Zj(i))/2._rp
       end do
       CB_ei=CB_ei_temp
       
    end if
    
  end function CB_ei
  
  function CB_ei_FIO(params,v)
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp) 				:: CB_ei_FIO
    REAL(rp) 				:: CB_ei_temp
    REAL(rp) 				:: x
    INTEGER :: i

    x = v/cparams_ss%VTe
    CB_ei_FIO  = (0.5_rp*cparams_ss%Gammac/v)*(cparams_ss%Zeff* &
         CLogei(v,cparams_ss%ne,cparams_ss%Te)/ &
         CLogee(v,cparams_ss%ne,cparams_ss%Te))


    if (params%bound_electron_model.eq.'HESSLOW') then
       CB_ei_temp=CB_ei_FIO
       do i=1,1
          CB_ei_temp=CB_ei_temp+CB_ei_FIO*cparams_ms%nz(i)/(cparams_ms%ne* &
               cparams_ss%Zeff*CLogei(v,cparams_ss%ne,cparams_ss%Te))* &
               g_j(i,v)
       end do
       CB_ei_FIO=CB_ei_temp
    end if
    
  end function CB_ei_FIO

  function CB_ee_SD(v,ne,Te,Zeff)
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp), INTENT(IN) 	:: Zeff
    REAL(rp) 				:: CB_ee_SD
    REAL(rp) 				:: x

    x = v/VTe(Te)
    CB_ee_SD  = (0.5_rp*Gammacee(v,ne,Te)/v)* &
         (ERF(x) - psi(x) + &
         0.5_rp*delta(Te)**4*x**2 )
  end function CB_ee_SD

  function CB_ei_SD(params,v,ne,Te,Zeff)
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp), INTENT(IN) 	:: Zeff
    REAL(rp) 				:: CB_ei_SD
    REAL(rp) 				:: CB_ei_temp
    REAL(rp) 				:: x
    INTEGER :: i

    x = v/VTe(Te)
    CB_ei_SD  = (0.5_rp*Gammacee(v,ne,Te)/v)* &
         (Zeff*CLogei(v,ne,Te)/CLogee(v,ne,Te))

    if (params%bound_electron_model.eq.'HESSLOW') then
       CB_ei_temp=CB_ei_SD
       if ((cparams_ms%Zj(1).eq.0.0).and. &
            (neut_prof.eq.'UNIFORM')) then
          CB_ei_temp=CB_ei_temp+CB_ei_SD*cparams_ms%nz(1)/(ne* &
               Zeff*CLogei(v,ne,Te))*g_j(1,v)
       else if ((cparams_ms%Zj(1).eq.0.0).and. &
            (neut_prof.eq.'HOLLOW')) then
          CB_ei_temp=CB_ei_temp+CB_ei_SD*max(cparams_ms%nz(1)-ne,0._rp)/(ne* &
               Zeff*CLogei(v,ne,Te))*g_j(1,v)
       else
          CB_ei_temp=CB_ei_temp+CB_ei_SD*cparams_ms%nz(1)/(cparams_ms%ne* &
               Zeff*CLogei(v,ne,Te))*g_j(1,v)
       endif
       
       do i=2,cparams_ms%num_impurity_species
          CB_ei_temp=CB_ei_temp+CB_ei_SD*cparams_ms%nz(i)/(cparams_ms%ne* &
               Zeff*CLogei(v,ne,Te))*g_j(i,v)
       end do
       CB_ei_SD=CB_ei_temp
       
    else if (params%bound_electron_model.eq.'ROSENBLUTH') then
       CB_ei_temp=CB_ei_SD
       do i=1,cparams_ms%num_impurity_species
          CB_ei_temp=CB_ei_temp+CB_ei_SD*cparams_ms%nz(i)/cparams_ms%ne* &
               (cparams_ms%Zo(i)-cparams_ms%Zj(i))/2._rp
       end do
       CB_ei_SD=CB_ei_temp
       
    end if
    
  end function CB_ei_SD
  
  function CB_ei_SD_FIO(params,v,ne,Te,nimp,Zeff)
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp), INTENT(IN) 	:: ne
    REAL(rp), INTENT(IN) 	:: Te
    REAL(rp), INTENT(IN) 	:: Zeff
    REAL(rp), DIMENSION(cparams_ms%num_impurity_species), INTENT(IN) 	:: nimp
    REAL(rp) 				:: CB_ei_SD_FIO
    REAL(rp) 				:: CB_ei_temp
    REAL(rp) 				:: x
    INTEGER :: i

    x = v/VTe(Te)
    CB_ei_SD_FIO  = (0.5_rp*Gammacee(v,ne,Te)/v)* &
         (Zeff*CLogei(v,ne,Te)/CLogee(v,ne,Te))

    if (params%bound_electron_model.eq.'HESSLOW') then
       CB_ei_temp=CB_ei_SD_FIO
       do i=1,cparams_ms%num_impurity_species
          CB_ei_temp=CB_ei_temp+CB_ei_SD_FIO*nimp(i)/(ne* &
               Zeff*CLogei(v,ne,Te))*g_j(i,v)
       end do
       CB_ei_SD_FIO=CB_ei_temp

    end if
    
  end function CB_ei_SD_FIO

  function nu_S(params,v)
    ! Slowing down collision frequency
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: v
      ! Normalised particle speed
    REAL(rp) 				:: nu_S
    REAL(rp) 				:: nu_S_temp
    REAL(rp) 				:: p
    
    p = v/SQRT(1.0_rp - v**2)
    nu_S = CF(params,v)/p
        
  end function nu_S

  function nu_S_FIO(params,v)
    ! Slowing down collision frequency
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
    REAL(rp), INTENT(IN) 	:: v
      ! Normalised particle speed
    REAL(rp) 				:: nu_S_FIO
    REAL(rp) 				:: nu_S_temp
    REAL(rp) 				:: p
    
    p = v/SQRT(1.0_rp - v**2)
    nu_S_FIO = CF_FIO(params,v)/p
        
  end function nu_S_FIO

  function h_j(i,v)
    INTEGER, INTENT(IN) 	:: i
    REAL(rp), INTENT(IN) 	:: v   
    REAL(rp)  :: gam
    REAL(rp)  :: p
    REAL(rp)  :: h_j

    gam=1/sqrt(1-v**2)
    p=v*gam
    
    h_j=p*sqrt(gam-1)/cparams_ms%IZj(i)
    
  end function h_j

  function g_j(i,v)
    INTEGER, INTENT(IN) 	:: i
    REAL(rp), INTENT(IN) 	:: v   
    REAL(rp)  :: gam
    REAL(rp)  :: p
    REAL(rp)  :: g_j

    gam=1/sqrt(1-v**2)
    p=v*gam
    
    g_j=2._rp/3._rp*((cparams_ms%Zo(i)**2-cparams_ms%Zj(i)**2)* &
         log((p*cparams_ms%aZj(i))**(3._rp/2._rp)+1)- &
         (cparams_ms%Zo(i)-cparams_ms%Zj(i))**2* &
         (p*cparams_ms%aZj(i))**(3._rp/2._rp)/ &
         ((p*cparams_ms%aZj(i))**(3._rp/2._rp)+1))

!    write(output_unit_write,'("g_j: ",E17.10)') g_j
    
  end function g_j

  function nu_D(params,v)
    ! perpendicular diffusion (pitch angle scattering) collision frequency
    REAL(rp), INTENT(IN) 	:: v
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
      ! Normalised particle speed
    REAL(rp) 				:: nu_D
    REAL(rp) 				:: p

    p = v/SQRT(1.0_rp - v**2)
    nu_D = 2.0_rp*(CB_ee(v)+CB_ei(params,v))/p**2
  end function nu_D

    function nu_D_FIO(params,v)
    ! perpendicular diffusion (pitch angle scattering) collision frequency
    REAL(rp), INTENT(IN) 	:: v
    TYPE(KORC_PARAMS), INTENT(IN) 	:: params
      ! Normalised particle speed
    REAL(rp) 				:: nu_D_FIO
    REAL(rp) 				:: p

    p = v/SQRT(1.0_rp - v**2)
    nu_D_FIO = 2.0_rp*(CB_ee(v)+CB_ei_FIO(params,v))/p**2
  end function nu_D_FIO


  function nu_par(v)
    ! parallel (speed diffusion) collision frequency
    REAL(rp), INTENT(IN) 	:: v
      ! Normalised particle speed
    REAL(rp) 				:: nu_par
    REAL(rp) 				:: p

    p = v/SQRT(1.0_rp - v**2)
    nu_par = 2.0_rp*CA(v)/p**2
  end function nu_par


  function fun(v)
    REAL(rp), INTENT(IN) 	:: v
    REAL(rp) 				:: fun
    REAL(rp) 				:: x

    x = v/cparams_ss%VTe
    fun = 2.0_rp*( 1.0_rp/x + x )*EXP(-x**2)/SQRT(C_PI) - ERF(x)/x**2 - psi(v)
  end function fun


  function cross(a,b)
    REAL(rp), DIMENSION(3), INTENT(IN) 	:: a
    REAL(rp), DIMENSION(3), INTENT(IN) 	:: b
    REAL(rp), DIMENSION(3) 				:: cross

    cross(1) = a(2)*b(3) - a(3)*b(2)
    cross(2) = a(3)*b(1) - a(1)*b(3)
    cross(3) = a(1)*b(2) - a(2)*b(1)
  end function cross

  subroutine unitVectorsC(B,b1,b2,b3)
    REAL(rp), DIMENSION(3), INTENT(IN) 	:: B
    REAL(rp), DIMENSION(3), INTENT(OUT) :: b1
    REAL(rp), DIMENSION(3), INTENT(OUT) :: b2
    REAL(rp), DIMENSION(3), INTENT(OUT) :: b3

    b1 = B/SQRT(DOT_PRODUCT(B,B))

    b2 = cross(b1,(/0.0_rp,0.0_rp,1.0_rp/))
    b2 = b2/SQRT(DOT_PRODUCT(b2,b2))

    b3 = cross(b1,b2)
    b3 = b3/SQRT(DOT_PRODUCT(b3,b3))
  end subroutine unitVectorsC

  subroutine unitVectors_p(pchunk,b_unit_X,b_unit_Y,b_unit_Z,b1_X,b1_Y,b1_Z, &
       b2_X,b2_Y,b2_Z,b3_X,b3_Y,b3_Z)
    INTEGER, INTENT(IN)  :: pchunk
    REAL(rp), DIMENSION(pchunk), INTENT(IN) 	:: b_unit_X,b_unit_Y,b_unit_Z
    REAL(rp), DIMENSION(pchunk), INTENT(OUT) :: b1_X,b1_Y,b1_Z
    REAL(rp), DIMENSION(pchunk), INTENT(OUT) :: b2_X,b2_Y,b2_Z
    REAL(rp), DIMENSION(pchunk), INTENT(OUT) :: b3_X,b3_Y,b3_Z
    REAL(rp), DIMENSION(pchunk) :: b2mag,b3mag
    integer(ip) :: cc

    !$OMP SIMD 
!    !$OMP& aligned(b1_X,b1_Y,b1_Z,b_unit_X,b_unit_Y,b_unit_Z, &
!    !$OMP& b2_X,b2_Y,b2_Z,b2mag,b3_X,b3_Y,b3_Z,b3mag)
    do cc=1_idef,pchunk
       b1_X(cc) = b_unit_X(cc)
       b1_Y(cc) = b_unit_Y(cc)
       b1_Z(cc) = b_unit_Z(cc)

       b2_X(cc) = b1_Y(cc)
       b2_Y(cc) = -b1_X(cc)
       b2_Z(cc) = 0._rp

       b2mag(cc)=sqrt(b2_X(cc)*b2_X(cc)+b2_Y(cc)*b2_Y(cc)+b2_Z(cc)*b2_Z(cc))

       b2_X(cc) = b2_X(cc)/b2mag(cc)
       b2_Y(cc) = b2_Y(cc)/b2mag(cc)
       b2_Z(cc) = b2_Z(cc)/b2mag(cc)

       b3_X(cc)=b1_Y(cc)*b2_Z(cc)-b1_Z(cc)*b2_Y(cc)
       b3_Y(cc)=b1_Z(cc)*b2_X(cc)-b1_X(cc)*b2_Z(cc)
       b3_Z(cc)=b1_X(cc)*b2_Y(cc)-b1_Y(cc)*b2_X(cc)

       b3mag(cc)=sqrt(b3_X(cc)*b3_X(cc)+b3_Y(cc)*b3_Y(cc)+b3_Z(cc)*b3_Z(cc))

       b3_X(cc) = b3_X(cc)/b3mag(cc)
       b3_Y(cc) = b3_Y(cc)/b3mag(cc)
       b3_Z(cc) = b3_Z(cc)/b3mag(cc)
    end do
    !$OMP END SIMD
    
  end subroutine unitVectors_p

  subroutine check_collisions_params(spp)
#ifdef PARALLEL_RANDOM
    USE omp_lib
#endif
    TYPE(SPECIES), INTENT(IN) :: spp
    INTEGER aux

    aux = cparams_ss%rnd_num_count + 2_idef*INT(spp%ppp,idef)

    if (aux.GE.cparams_ss%rnd_dim) then
#ifdef PARALLEL_RANDOM
       cparams_ss%rnd_num = get_random()
#else
       call RANDOM_NUMBER(cparams_ss%rnd_num)
#endif
       cparams_ss%rnd_num_count = 1_idef
    end if
  end subroutine check_collisions_params

  ! * * * * * * * * * * * *  * * * * * * * * * * * * * * * * * * * !
  ! * FUNCTIONS OF COLLISION OPERATOR FOR SINGLE-SPECIES PLASMAS * !
  ! * * * * * * * * * * * *  * * * * * * * * * * * * * * * * * * * !




  subroutine include_CoulombCollisions_FO_p(tt,params,X_X,X_Y,X_Z, &
       U_X,U_Y,U_Z,B_X,B_Y,B_Z,me,P,F,flagCon,flagCol,PSIp)
    !! This subroutine performs a Stochastic collision process consistent
    !! with the Fokker-Planck model for relativitic electron colliding with
    !! a thermal (Maxwellian) plasma. The collision operator is in spherical
    !! coordinates of the form found in Papp et al., NF (2011). CA
    !! corresponds to the parallel (speed diffusion) process, CF corresponds
    !! to a slowing down (momentum loss) process, and CB corresponds to a
    !! perpendicular diffusion process. Ordering of the processes are
    !! $$ \sqrt{CB}\gg CB \gg CF \sim \sqrt{CA} \gg CA,$$
    !! and only the dominant terms are kept.
    TYPE(PROFILES), INTENT(IN)                                 :: P
    TYPE(FIELDS), INTENT(IN)      :: F
    TYPE(KORC_PARAMS), INTENT(IN) 		:: params
    REAL(rp), DIMENSION(params%pchunk), INTENT(IN) 	:: X_X,X_Y,X_Z,PSIp
    REAL(rp), DIMENSION(params%pchunk)  	:: Y_R,Y_PHI,Y_Z
    REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) 	:: U_X,U_Y,U_Z

    REAL(rp), DIMENSION(params%pchunk) 			:: ne,Te,Zeff
    INTEGER(is), DIMENSION(params%pchunk), INTENT(INOUT) 			:: flagCol
    INTEGER(is), DIMENSION(params%pchunk), INTENT(INOUT) 			:: flagCon
    REAL(rp), INTENT(IN)  :: me

    INTEGER(ip), INTENT(IN) 			:: tt

    REAL(rp), DIMENSION(params%pchunk), INTENT(IN) 		:: B_X,B_Y,B_Z

    REAL(rp), DIMENSION(params%pchunk) 		:: b_unit_X,b_unit_Y,b_unit_Z
    REAL(rp), DIMENSION(params%pchunk) 		:: b1_X,b1_Y,b1_Z
    REAL(rp), DIMENSION(params%pchunk) 		:: b2_X,b2_Y,b2_Z
    REAL(rp), DIMENSION(params%pchunk) 		:: b3_X,b3_Y,b3_Z
    REAL(rp), DIMENSION(params%pchunk) 		:: Bmag

    
    REAL(rp), DIMENSION(params%pchunk,3) 			:: dW
    !! 3D Weiner process
    REAL(rp), DIMENSION(params%pchunk,3) 			:: rnd1

    REAL(rp) 					:: dt,time
    REAL(rp), DIMENSION(params%pchunk) 					:: um
    REAL(rp), DIMENSION(params%pchunk) 					:: dpm
    REAL(rp), DIMENSION(params%pchunk) 					:: vm
    REAL(rp), DIMENSION(params%pchunk) 					:: pm

    REAL(rp),DIMENSION(params%pchunk) 			:: Ub_X,Ub_Y,Ub_Z
    REAL(rp), DIMENSION(params%pchunk) 			:: xi
    REAL(rp), DIMENSION(params%pchunk) 			:: dxi
    REAL(rp), DIMENSION(params%pchunk)  			:: phi
    REAL(rp), DIMENSION(params%pchunk)  			:: dphi
    !! speed of particle
    REAL(rp),DIMENSION(params%pchunk) 					:: CAL
    REAL(rp),DIMENSION(params%pchunk) 					:: dCAL
    REAL(rp),DIMENSION(params%pchunk) 					:: CFL
    REAL(rp),DIMENSION(params%pchunk) 					:: CBL

    integer :: cc,pchunk

    pchunk=params%pchunk
    
    if (MODULO(params%it+tt,cparams_ss%subcycling_iterations) .EQ. 0_ip) then
       dt = REAL(cparams_ss%subcycling_iterations,rp)*params%dt
       time=params%init_time+(params%it-1+tt)*params%dt
       ! subcylcling iterations a fraction of fastest collision frequency,
       ! where fraction set by dTau in namelist &CollisionParamsSingleSpecies

       call cart_to_cyl_p(pchunk,X_X,X_Y,X_Z,Y_R,Y_PHI,Y_Z)

       if (params%profile_model(1:10).eq.'ANALYTICAL') then
          call analytical_profiles_p(pchunk,time,params,Y_R,Y_Z,P,F,ne,Te,Zeff,PSIp)
       else  if (params%profile_model(1:8).eq.'EXTERNAL') then
#ifdef PSPLINE
          call interp_FOcollision_p(pchunk,Y_R,Y_PHI,Y_Z,ne,Te,Zeff,flagCon)
#endif
       end if
          
       !$OMP SIMD
!       !$OMP& aligned(um,pm,vm,U_X,U_Y,U_Z,Bmag,B_X,B_Y,B_Z, &
!       !$OMP& b_unit_X,b_unit_Y,b_unit_Z,xi)
       do cc=1_idef,pchunk

          um(cc) = SQRT(U_X(cc)*U_X(cc)+U_Y(cc)*U_Y(cc)+U_Z(cc)*U_Z(cc))
          pm(cc)=me*um(cc)
          vm(cc) = um(cc)/SQRT(1.0_rp + um(cc)*um(cc))
          ! um is gamma times v, this solves for v
          
          Bmag(cc)= SQRT(B_X(cc)*B_X(cc)+B_Y(cc)*B_Y(cc)+B_Z(cc)*B_Z(cc))

          b_unit_X(cc)=B_X(cc)/Bmag(cc)
          b_unit_Y(cc)=B_Y(cc)/Bmag(cc)
          b_unit_Z(cc)=B_Z(cc)/Bmag(cc)

          xi(cc)=(U_X(cc)*b_unit_X(cc)+U_Y(cc)*b_unit_Y(cc)+ &
               U_Z(cc)*b_unit_Z(cc))/um(cc)
          
          ! pitch angle in b_unit reference frame
       end do
       !$OMP END SIMD

!       write(output_unit_write,'("vm: ",E17.10)') vm
!       write(output_unit_write,'("xi: ",E17.10)') xi
       
       call unitVectors_p(pchunk,b_unit_X,b_unit_Y,b_unit_Z,b1_X,b1_Y,b1_Z, &
            b2_X,b2_Y,b2_Z,b3_X,b3_Y,b3_Z)
          ! b1=b_unit, (b1,b2,b3) is right-handed

       !$OMP SIMD
!       !$OMP& aligned(phi,U_X,U_Y,U_Z,b3_X,b3_Y,b3_Z,b2_X,b2_Y,b2_Z)
       do cc=1_idef,pchunk
          phi(cc) = atan2((U_X(cc)*b3_X(cc)+U_Y(cc)*b3_Y(cc)+ &
               U_Z(cc)*b3_Z(cc)), &
               (U_X(cc)*b2_X(cc)+U_Y(cc)*b2_Y(cc)+U_Z(cc)*b2_Z(cc)))
          ! azimuthal angle in b_unit refernce frame
       end do
       !$OMP END SIMD

!       write(output_unit_write,'("phi: ",E17.10)') phi
       
       !$OMP SIMD
!       !$OMP& aligned(rnd1,dW,CAL,dCAL,CFL,CBL,vm,ne,Te,Zeff,dpm, &
!       !$OMP& flagCon,flagCol,dxi,xi,pm,dphi,um,Ub_X,Ub_Y,Ub_Z,U_X,U_Y,U_Z, &
!       !$OMP& b1_X,b1_Y,b1_Z,b2_X,b2_Y,b2_Z,b3_X,b3_Y,b3_Z)
       do cc=1_idef,pchunk
          
#ifdef PARALLEL_RANDOM
          ! uses C library to generate normal_distribution random variables,
          ! preserving parallelization where Fortran random number generator
          ! does not
          rnd1(cc,1) = get_random()
          rnd1(cc,2) = get_random()
          rnd1(cc,3) = get_random()
#else
          call RANDOM_NUMBER(rnd1)
#endif

          dW(cc,1) = SQRT(3*dt)*(-1+2*rnd1(cc,1))     
          dW(cc,2) = SQRT(3*dt)*(-1+2*rnd1(cc,2))
          dW(cc,3) = SQRT(3*dt)*(-1+2*rnd1(cc,3)) 
          ! 3D Weiner process 

          CAL(cc) = CA_SD(vm(cc),ne(cc),Te(cc))
          dCAL(cc)= dCA_SD(vm(cc),me,ne(cc),Te(cc))
          CFL(cc) = CF_SD(params,vm(cc),ne(cc),Te(cc))
          CBL(cc) = (CB_ee_SD(vm(cc),ne(cc),Te(cc),Zeff(cc))+ &
               CB_ei_SD(params,vm(cc),ne(cc),Te(cc),Zeff(cc)))


          dpm(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
               ((-CFL(cc)+dCAL(cc))*dt+ &
               sqrt(2.0_rp*CAL(cc))*dW(cc,1))
          dxi(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
               (-2*xi(cc)*CBL(cc)/(pm(cc)*pm(cc))*dt- &
               sqrt(2.0_rp*CBL(cc)*(1-xi(cc)*xi(cc)))/pm(cc)*dW(cc,2))
          dphi(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
               (sqrt(2*CBL(cc))/(pm(cc)* &
               sqrt(1-xi(cc)*xi(cc)))*dW(cc,3))

          pm(cc)=pm(cc)+dpm(cc)
          xi(cc)=xi(cc)+dxi(cc)
          phi(cc)=phi(cc)+dphi(cc)

!          if (pm(cc)<0) pm(cc)=-pm(cc)

          ! Keep xi between [-1,1]
          if (xi(cc)>1) then
             xi(cc)=1-mod(xi(cc),1._rp)
          else if (xi(cc)<-1) then
             xi(cc)=-1-mod(xi(cc),-1._rp)             
          endif

          ! Keep phi between [0,pi]
!          if (phi(cc)>C_PI) then
!             phi(cc)=C_PI-mod(phi(cc),C_PI)
!          else if (phi(cc)<0) then
!             phi(cc)=mod(-phi(cc),C_PI)             
!          endif
          
          um(cc)=pm(cc)/me

          Ub_X(cc)=um(cc)*xi(cc)
          Ub_Y(cc)=um(cc)*sqrt(1-xi(cc)*xi(cc))*cos(phi(cc))
          Ub_Z(cc)=um(cc)*sqrt(1-xi(cc)*xi(cc))*sin(phi(cc))

          U_X(cc) = Ub_X(cc)*b1_X(cc)+Ub_Y(cc)*b2_X(cc)+Ub_Z(cc)*b3_X(cc)
          U_Y(cc) = Ub_X(cc)*b1_Y(cc)+Ub_Y(cc)*b2_Y(cc)+Ub_Z(cc)*b3_Y(cc)
          U_Z(cc) = Ub_X(cc)*b1_Z(cc)+Ub_Y(cc)*b2_Z(cc)+Ub_Z(cc)*b3_Z(cc)

       end do
       !$OMP END SIMD
       
!       if (tt .EQ. 1_ip) then
!          write(output_unit_write,'("CA: ",E17.10)') CAL(1)
!          write(output_unit_write,'("dCA: ",E17.10)') dCAL(1)
!          write(output_unit_write,'("CF ",E17.10)') CFL(1)
!          write(output_unit_write,'("CB: ",E17.10)') CBL(1)
!       end if

       
       do cc=1_idef,pchunk
          if (pm(cc).lt.0) then
             write(output_unit_write,'("Momentum less than zero")')
             stop
          end if
       end do
       
    end if
  end subroutine include_CoulombCollisions_FO_p

#ifdef FIO
  subroutine include_CoulombCollisions_FOfio_p(tt,params,X_X,X_Y,X_Z, &
       U_X,U_Y,U_Z,B_X,B_Y,B_Z,me,P,F,flagCon,flagCol,PSIp,hint)
    !! This subroutine performs a Stochastic collision process consistent
    !! with the Fokker-Planck model for relativitic electron colliding with
    !! a thermal (Maxwellian) plasma. The collision operator is in spherical
    !! coordinates of the form found in Papp et al., NF (2011). CA
    !! corresponds to the parallel (speed diffusion) process, CF corresponds
    !! to a slowing down (momentum loss) process, and CB corresponds to a
    !! perpendicular diffusion process. Ordering of the processes are
    !! $$ \sqrt{CB}\gg CB \gg CF \sim \sqrt{CA} \gg CA,$$
    !! and only the dominant terms are kept.
    TYPE(PROFILES), INTENT(IN)                                 :: P
    TYPE(FIELDS), INTENT(IN)      :: F
    TYPE(KORC_PARAMS), INTENT(IN) 		:: params
    REAL(rp), DIMENSION(params%pchunk), INTENT(IN) 	:: X_X,X_Y,X_Z,PSIp
    REAL(rp), DIMENSION(params%pchunk)  	:: Y_R,Y_PHI,Y_Z
    REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) 	:: U_X,U_Y,U_Z

    REAL(rp), DIMENSION(params%pchunk) 			:: ne,Te,Zeff,ni
    REAL(rp), DIMENSION(params%pchunk,params%num_impurity_species) 	:: nimp
    INTEGER(is), DIMENSION(params%pchunk), INTENT(INOUT) 			:: flagCol
    INTEGER(is), DIMENSION(params%pchunk), INTENT(INOUT) 			:: flagCon
    REAL(rp), INTENT(IN)  :: me

    INTEGER(ip), INTENT(IN) 			:: tt

    REAL(rp), DIMENSION(params%pchunk), INTENT(IN) 		:: B_X,B_Y,B_Z
    TYPE(C_PTR),DIMENSION(params%pchunk) :: hint

    REAL(rp), DIMENSION(params%pchunk) 		:: b_unit_X,b_unit_Y,b_unit_Z
    REAL(rp), DIMENSION(params%pchunk) 		:: b1_X,b1_Y,b1_Z
    REAL(rp), DIMENSION(params%pchunk) 		:: b2_X,b2_Y,b2_Z
    REAL(rp), DIMENSION(params%pchunk) 		:: b3_X,b3_Y,b3_Z
    REAL(rp), DIMENSION(params%pchunk) 		:: Bmag

    
    REAL(rp), DIMENSION(params%pchunk,3) 			:: dW
    !! 3D Weiner process
    REAL(rp), DIMENSION(params%pchunk,3) 			:: rnd1

    REAL(rp) 					:: dt,time
    REAL(rp), DIMENSION(params%pchunk) 					:: um
    REAL(rp), DIMENSION(params%pchunk) 					:: dpm
    REAL(rp), DIMENSION(params%pchunk) 					:: vm
    REAL(rp), DIMENSION(params%pchunk) 					:: pm

    REAL(rp),DIMENSION(params%pchunk) 			:: Ub_X,Ub_Y,Ub_Z
    REAL(rp), DIMENSION(params%pchunk) 			:: xi
    REAL(rp), DIMENSION(params%pchunk) 			:: dxi
    REAL(rp), DIMENSION(params%pchunk)  			:: phi
    REAL(rp), DIMENSION(params%pchunk)  			:: dphi
    !! speed of particle
    REAL(rp),DIMENSION(params%pchunk) 					:: CAL
    REAL(rp),DIMENSION(params%pchunk) 					:: dCAL
    REAL(rp),DIMENSION(params%pchunk) 					:: CFL
    REAL(rp),DIMENSION(params%pchunk) 					:: CBL

    integer :: cc,pchunk

    pchunk=params%pchunk
    
    if (MODULO(params%it+tt,cparams_ss%subcycling_iterations) .EQ. 0_ip) then
       dt = REAL(cparams_ss%subcycling_iterations,rp)*params%dt
       time=params%init_time+(params%it-1+tt)*params%dt
       ! subcylcling iterations a fraction of fastest collision frequency,
       ! where fraction set by dTau in namelist &CollisionParamsSingleSpecies

       call cart_to_cyl_p(pchunk,X_X,X_Y,X_Z,Y_R,Y_PHI,Y_Z)

       call get_fio_profile_p(params,P,Y_R,Y_PHI,Y_Z, &
            ne,Te,flagCon,hint)

       call get_fio_ion_p(params,P,Y_R,Y_PHI,Y_Z, &
            ne,ni,nimp,Zeff,flagCon,hint)

       !write(6,*) ne,Te,nimp,Zeff
       
       !$OMP SIMD
!       !$OMP& aligned(um,pm,vm,U_X,U_Y,U_Z,Bmag,B_X,B_Y,B_Z, &
!       !$OMP& b_unit_X,b_unit_Y,b_unit_Z,xi)
       do cc=1_idef,pchunk

          um(cc) = SQRT(U_X(cc)*U_X(cc)+U_Y(cc)*U_Y(cc)+U_Z(cc)*U_Z(cc))
          pm(cc)=me*um(cc)
          vm(cc) = um(cc)/SQRT(1.0_rp + um(cc)*um(cc))
          ! um is gamma times v, this solves for v
          
          Bmag(cc)= SQRT(B_X(cc)*B_X(cc)+B_Y(cc)*B_Y(cc)+B_Z(cc)*B_Z(cc))

          b_unit_X(cc)=B_X(cc)/Bmag(cc)
          b_unit_Y(cc)=B_Y(cc)/Bmag(cc)
          b_unit_Z(cc)=B_Z(cc)/Bmag(cc)

          xi(cc)=(U_X(cc)*b_unit_X(cc)+U_Y(cc)*b_unit_Y(cc)+ &
               U_Z(cc)*b_unit_Z(cc))/um(cc)
          
          ! pitch angle in b_unit reference frame
       end do
       !$OMP END SIMD

!       write(output_unit_write,'("vm: ",E17.10)') vm
!       write(output_unit_write,'("xi: ",E17.10)') xi
       
       call unitVectors_p(pchunk,b_unit_X,b_unit_Y,b_unit_Z,b1_X,b1_Y,b1_Z, &
            b2_X,b2_Y,b2_Z,b3_X,b3_Y,b3_Z)
          ! b1=b_unit, (b1,b2,b3) is right-handed

       !$OMP SIMD
!       !$OMP& aligned(phi,U_X,U_Y,U_Z,b3_X,b3_Y,b3_Z,b2_X,b2_Y,b2_Z)
       do cc=1_idef,pchunk
          phi(cc) = atan2((U_X(cc)*b3_X(cc)+U_Y(cc)*b3_Y(cc)+ &
               U_Z(cc)*b3_Z(cc)), &
               (U_X(cc)*b2_X(cc)+U_Y(cc)*b2_Y(cc)+U_Z(cc)*b2_Z(cc)))
          ! azimuthal angle in b_unit refernce frame
       end do
       !$OMP END SIMD

!       write(output_unit_write,'("phi: ",E17.10)') phi
       
       !$OMP SIMD
!       !$OMP& aligned(rnd1,dW,CAL,dCAL,CFL,CBL,vm,ne,Te,Zeff,nimp,dpm, &
!       !$OMP& flagCon,flagCol,dxi,xi,pm,dphi,um,Ub_X,Ub_Y,Ub_Z,U_X,U_Y,U_Z, &
!       !$OMP& b1_X,b1_Y,b1_Z,b2_X,b2_Y,b2_Z,b3_X,b3_Y,b3_Z)
       do cc=1_idef,pchunk
          
#ifdef PARALLEL_RANDOM
          ! uses C library to generate normal_distribution random variables,
          ! preserving parallelization where Fortran random number generator
          ! does not
          rnd1(cc,1) = get_random()
          rnd1(cc,2) = get_random()
          rnd1(cc,3) = get_random()
#else
          call RANDOM_NUMBER(rnd1)
#endif

          dW(cc,1) = SQRT(3*dt)*(-1+2*rnd1(cc,1))     
          dW(cc,2) = SQRT(3*dt)*(-1+2*rnd1(cc,2))
          dW(cc,3) = SQRT(3*dt)*(-1+2*rnd1(cc,3)) 
          ! 3D Weiner process 

          CAL(cc) = CA_SD(vm(cc),ne(cc),Te(cc))
          dCAL(cc)= dCA_SD(vm(cc),me,ne(cc),Te(cc))
          CFL(cc) = CF_SD(params,vm(cc),ne(cc),Te(cc))
          CBL(cc) = (CB_ee_SD(vm(cc),ne(cc),Te(cc),Zeff(cc))+ &
               CB_ei_SD(params,vm(cc),ne(cc),Te(cc),Zeff(cc)))


          dpm(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
               ((-CFL(cc)+dCAL(cc))*dt+ &
               sqrt(2.0_rp*CAL(cc))*dW(cc,1))
          dxi(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
               (-2*xi(cc)*CBL(cc)/(pm(cc)*pm(cc))*dt- &
               sqrt(2.0_rp*CBL(cc)*(1-xi(cc)*xi(cc)))/pm(cc)*dW(cc,2))
          dphi(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
               (sqrt(2*CBL(cc))/(pm(cc)* &
               sqrt(1-xi(cc)*xi(cc)))*dW(cc,3))

          pm(cc)=pm(cc)+dpm(cc)
          xi(cc)=xi(cc)+dxi(cc)
          phi(cc)=phi(cc)+dphi(cc)

!          if (pm(cc)<0) pm(cc)=-pm(cc)

          ! Keep xi between [-1,1]
          if (xi(cc)>1) then
             xi(cc)=1-mod(xi(cc),1._rp)
          else if (xi(cc)<-1) then
             xi(cc)=-1-mod(xi(cc),-1._rp)             
          endif

          ! Keep phi between [0,pi]
!          if (phi(cc)>C_PI) then
!             phi(cc)=C_PI-mod(phi(cc),C_PI)
!          else if (phi(cc)<0) then
!             phi(cc)=mod(-phi(cc),C_PI)             
!          endif
          
          um(cc)=pm(cc)/me

          Ub_X(cc)=um(cc)*xi(cc)
          Ub_Y(cc)=um(cc)*sqrt(1-xi(cc)*xi(cc))*cos(phi(cc))
          Ub_Z(cc)=um(cc)*sqrt(1-xi(cc)*xi(cc))*sin(phi(cc))

          U_X(cc) = Ub_X(cc)*b1_X(cc)+Ub_Y(cc)*b2_X(cc)+Ub_Z(cc)*b3_X(cc)
          U_Y(cc) = Ub_X(cc)*b1_Y(cc)+Ub_Y(cc)*b2_Y(cc)+Ub_Z(cc)*b3_Y(cc)
          U_Z(cc) = Ub_X(cc)*b1_Z(cc)+Ub_Y(cc)*b2_Z(cc)+Ub_Z(cc)*b3_Z(cc)

       end do
       !$OMP END SIMD
       
!       if (tt .EQ. 1_ip) then
!          write(output_unit_write,'("CA: ",E17.10)') CAL(1)
!          write(output_unit_write,'("dCA: ",E17.10)') dCAL(1)
!          write(output_unit_write,'("CF ",E17.10)') CFL(1)
!          write(output_unit_write,'("CB: ",E17.10)') CBL(1)
!       end if

       
       do cc=1_idef,pchunk
          if (pm(cc).lt.0) then
             write(output_unit_write,'("Momentum less than zero")')
             stop
          end if
       end do
       
    end if
  end subroutine include_CoulombCollisions_FOfio_p
#endif
  
  subroutine include_CoulombCollisions_GC_p(tt,params,Y_R,Y_PHI,Y_Z, &
       Ppll,Pmu,me,flagCon,flagCol,F,P,E_PHI,ne,PSIp)

    TYPE(PROFILES), INTENT(IN)                                 :: P
    TYPE(FIELDS), INTENT(IN)                                   :: F
    TYPE(KORC_PARAMS), INTENT(INOUT) 		:: params
    REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) 	:: Ppll
    REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) 	:: Pmu
    REAL(rp), DIMENSION(params%pchunk) 			:: Bmag
    REAL(rp), DIMENSION(params%pchunk) 	:: B_R,B_PHI,B_Z
    REAL(rp), DIMENSION(params%pchunk) :: curlb_R,curlb_PHI,curlb_Z
    REAL(rp), DIMENSION(params%pchunk) :: gradB_R,gradB_PHI,gradB_Z
    REAL(rp), DIMENSION(params%pchunk) 	:: E_R,E_Z
    REAL(rp), DIMENSION(params%pchunk), INTENT(OUT) 	:: E_PHI,ne,PSIp
    REAL(rp), DIMENSION(params%pchunk), INTENT(IN) 			:: Y_R,Y_PHI,Y_Z
    INTEGER(is), DIMENSION(params%pchunk), INTENT(INOUT) 	:: flagCol
    INTEGER(is), DIMENSION(params%pchunk), INTENT(INOUT) 	:: flagCon
    REAL(rp), INTENT(IN) 			:: me
    REAL(rp), DIMENSION(params%pchunk) 			:: Te,Zeff
    REAL(rp), DIMENSION(params%pchunk) 			:: nAr0,nAr1,nAr2,nAr3
    REAL(rp), DIMENSION(params%pchunk) 			:: nD,nD1
    REAL(rp), DIMENSION(params%pchunk,2) 			:: dW
    REAL(rp), DIMENSION(params%pchunk,2) 			:: rnd1
    REAL(rp) 					:: dt,time
    REAL(rp), DIMENSION(params%pchunk) 					:: pm
    REAL(rp), DIMENSION(params%pchunk)  					:: dp
    REAL(rp), DIMENSION(params%pchunk)  					:: xi
    REAL(rp), DIMENSION(params%pchunk)  					:: dxi
    REAL(rp), DIMENSION(params%pchunk)  					:: v,gam
    !! speed of particle
    REAL(rp), DIMENSION(params%pchunk) 					:: CAL
    REAL(rp) , DIMENSION(params%pchunk)					:: dCAL
    REAL(rp), DIMENSION(params%pchunk) 					:: CFL
    REAL(rp), DIMENSION(params%pchunk) 					:: CBL
    REAL(rp), DIMENSION(params%pchunk) 	:: SC_p,SC_mu,BREM_p
    REAL(rp) 					:: kappa
    integer :: cc,pchunk
    integer(ip),INTENT(IN) :: tt
    REAL(rp), DIMENSION(params%pchunk,params%num_impurity_species) 	:: nimp
    
    pchunk=params%pchunk
    
    if (MODULO(params%it+tt,cparams_ss%subcycling_iterations) .EQ. 0_ip) then
       dt = REAL(cparams_ss%subcycling_iterations,rp)*params%dt       
       time=params%init_time+(params%it-1+tt)*params%dt


       if (params%field_eval.eq.'eqn') then
          call analytical_fields_GC_p(pchunk,F,Y_R,Y_PHI, &
               Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
               gradB_R,gradB_PHI,gradB_Z,PSIp)          
       else if (params%field_eval.eq.'interp') then
#ifdef PSPLINE
          if (F%axisymmetric_fields) then
             if (F%Bflux) then
                if (.not.params%SC_E) then
                   call calculate_GCfields_p(pchunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                        E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                        gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp)
                else
                   call calculate_GCfields_p_FS(pchunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                        E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                        gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp)
                end if

             else if (F%ReInterp_2x1t) then
                call calculate_GCfieldswE_p(pchunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                     E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                     gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp)
             else if (F%Bflux3D) then
                call calculate_GCfields_2x1t_p(pchunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                     E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                     gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp,time)
             else if (F%dBfield) then
                call calculate_2DBdBfields_p(pchunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                     E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                     gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp)
             else
                call interp_fields_p(pchunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                     E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                     gradB_R,gradB_PHI,gradB_Z,flagCon)
             end if
          else
             if (F%dBfield) then
                call calculate_2DBdBfields_p(pchunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                     E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                     gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp)
             else
                call interp_fields_3D_p(pchunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                     E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                     gradB_R,gradB_PHI,gradB_Z,flagCon)
             end if
          endif
          call add_analytical_E_p(params,tt,F,E_PHI,Y_R,Y_Z)
#endif
       end if


       if (params%profile_model(1:10).eq.'ANALYTICAL') then
          call analytical_profiles_p(pchunk,time,params,Y_R,Y_Z,P,F,ne,Te,Zeff,PSIp)
       else if (params%profile_model(1:8).eq.'EXTERNAL') then
#ifdef PSPLINE
          if (params%profile_model(10:10).eq.'H') then
             call interp_Hcollision_p(pchunk,Y_R,Y_PHI,Y_Z,ne,Te,Zeff, &
                  nAr0,nAr1,nAr2,nAr3,nD,nD1,flagCon)
             do cc=1_idef,pchunk
                nimp(cc,1)=nAr0(cc)
                nimp(cc,2)=nAr1(cc)
                nimp(cc,3)=nAr2(cc)
                nimp(cc,4)=nAr3(cc)
                nimp(cc,5)=nD(cc)
                nimp(cc,6)=nD1(cc)
             end do
          else
             call interp_FOcollision_p(pchunk,Y_R,Y_PHI,Y_Z,ne,Te,Zeff,flagCon)
          endif
#endif
       end if
       
       if (.not.params%FokPlan) E_PHI=0._rp
       
       !$OMP SIMD
!       !$OMP& aligned (pm,xi,v,Ppll,Bmag,Pmu)
       do cc=1_idef,pchunk
          Bmag(cc)=sqrt(B_R(cc)*B_R(cc)+B_PHI(cc)*B_PHI(cc)+B_Z(cc)*B_Z(cc))
          ! Transform p_pll,mu to P,eta
          pm(cc) = SQRT(Ppll(cc)*Ppll(cc)+2*me*Bmag(cc)*Pmu(cc))
          xi(cc) = Ppll(cc)/pm(cc)

          gam(cc) = sqrt(1+pm(cc)*pm(cc))
          
          v(cc) = pm(cc)/gam(cc)
          ! normalized speed (v_K=v_P/c)
       end do
       !$OMP END SIMD

!       write(output_unit_write,'("ne: "E17.10)') ne
!       write(output_unit_write,'("Te: "E17.10)') Te
!       write(output_unit_write,'("Bmag: "E17.10)') Bmag                
!       write(output_unit_write,'("v: ",E17.10)') v
!       write(output_unit_write,'("xi: ",E17.10)') xi
       !       write(output_unit_write,'("size(E_PHI_GC): ",I16)') size(E_PHI)


       !$OMP SIMD
!       !$OMP& aligned(rnd1,dW,CAL,dCAL,CFL,CBL,v,ne,Te,Zeff,dp, &
!       !$OMP& flagCon,flagCol,dxi,xi,pm,Ppll,Pmu,Bmag)
       do cc=1_idef,pchunk
       
#ifdef PARALLEL_RANDOM
          rnd1(cc,1) = get_random()
          rnd1(cc,2) = get_random()
          !       rnd1(:,1) = get_random_mkl()
          !       rnd1(:,2) = get_random_mkl()
#else
          call RANDOM_NUMBER(rnd1)
#endif
          
          dW(cc,1) = SQRT(3*dt)*(-1+2*rnd1(cc,1))     
          dW(cc,2) = SQRT(3*dt)*(-1+2*rnd1(cc,2))     

!          write(output_unit_write,'("dW1: ",E17.10)') dW(cc,1)
!          write(output_unit_write,'("dW2: ",E17.10)') dW(cc,2)

          if (params%profile_model(10:10).eq.'H') then
             CAL(cc) = CA_SD(v(cc),ne(cc),Te(cc))
             dCAL(cc)= dCA_SD(v(cc),me,ne(cc),Te(cc))
             CFL(cc) = CF_SD_FIO(params,v(cc),ne(cc),Te(cc),nimp(cc,:))
             CBL(cc) = (CB_ee_SD(v(cc),ne(cc),Te(cc),Zeff(cc))+ &
                  CB_ei_SD_FIO(params,v(cc),ne(cc),Te(cc),nimp(cc,:),Zeff(cc)))
          else
             CAL(cc) = CA_SD(v(cc),ne(cc),Te(cc))
             dCAL(cc)= dCA_SD(v(cc),me,ne(cc),Te(cc))
             CFL(cc) = CF_SD(params,v(cc),ne(cc),Te(cc))
             CBL(cc) = (CB_ee_SD(v(cc),ne(cc),Te(cc),Zeff(cc))+ &
                  CB_ei_SD(params,v(cc),ne(cc),Te(cc),Zeff(cc)))
          endif
          
          
          dp(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
               ((-CFL(cc)+dCAL(cc)+E_PHI(cc)*xi(cc))*dt+ &
               sqrt(2.0_rp*CAL(cc))*dW(cc,1))

          dxi(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
               ((-2*xi(cc)*CBL(cc)/(pm(cc)*pm(cc))+ &
               E_PHI(cc)*(1-xi(cc)*xi(cc))/pm(cc))*dt- &
               sqrt(2.0_rp*CBL(cc)*(1-xi(cc)*xi(cc)))/pm(cc)*dW(cc,2))

!          write(output_unit_write,'("dp: ",E17.10)') dp(cc)
!          write(output_unit_write,'("dxi: ",E17.10)') dxi(cc)

       end do
       !$OMP END SIMD
          
       if (params%FokPlan.and.params%radiation) then
          if(params%GC_rad_model.eq.'SDE') then

             !$OMP SIMD
             do cc=1_idef,pchunk

                SC_p(cc)=-gam(cc)*pm(cc)*(1-xi(cc)*xi(cc))/ &
                     (cparams_ss%taur/Bmag(cc)**2)
                SC_mu(cc)=xi(cc)*(1-xi(cc)*xi(cc))/ &
                     ((cparams_ss%taur/Bmag(cc)**2)*gam(cc))

                kappa=2._rp*C_PI*C_RE**2._rp*C_ME*C_C**2._rp
                BREM_p(cc)=-2._rp*ne(cc)*kappa*Zeff(cc)*(Zeff(cc)+1._rp)* &
                     C_a/C_PI*(gam(cc)-1._rp)*(log(2._rp*gam(cc))-1._rp/3._rp)


                dp(cc)=dp(cc)+(SC_p(cc)+BREM_p(cc))*dt* &
                     REAL(flagCol(cc))*REAL(flagCon(cc))
                dxi(cc)=dxi(cc)+(SC_mu(cc))*dt* &
                     REAL(flagCol(cc))*REAL(flagCon(cc))

             end do
             !$OMP END SIMD

          end if
       end if

       !$OMP SIMD
       do cc=1_idef,pchunk  

          pm(cc)=pm(cc)+dp(cc)
          xi(cc)=xi(cc)+dxi(cc)
       end do
       !$OMP END SIMD

       do cc=1_idef,pchunk 
!          if (pm(cc)<0) pm(cc)=-pm(cc)

          ! Keep xi between [-1,1]
          if (xi(cc)>1) then
!             write(output_unit_write,'("High xi at: ",E17.10," with dxi: ",E17.10)') &
!                  time*params%cpp%time, dxi(cc)
             xi(cc)=1-mod(xi(cc),1._rp)
          else if (xi(cc)<-1) then
             xi(cc)=-1-mod(xi(cc),-1._rp)
!             write(output_unit_write,'("Low xi at: ",E17.10," with dxi: ",E17.10)') &
!                  time*params%cpp%time, dxi(cc)
          endif

       end do

       !$OMP SIMD
       do cc=1_idef,pchunk  
          ! Transform P,xi to p_pll,mu
          Ppll(cc)=pm(cc)*xi(cc)
          Pmu(cc)=(pm(cc)*pm(cc)-Ppll(cc)*Ppll(cc))/(2*me*Bmag(cc))
       end do
       !$OMP END SIMD


!       write(output_unit_write,'("rnd1: ",E17.10)') rnd1
!       write(output_unit_write,'("flag: ",I16)') flag
!       write(output_unit_write,'("CA: ",E17.10)') CAL
!       write(output_unit_write,'("dCA: ",E17.10)') dCAL
!       write(output_unit_write,'("CF ",E17.10)') CFL
!       write(output_unit_write,'("CB: ",E17.10)') CBL
!       write(output_unit_write,'("dp: ",E17.10)') dp
!       write(output_unit_write,'("dxi: ",E17.10)') dxi
!       write(output_unit_write,'("Ppll: ",E17.10)') Ppll
!      write(output_unit_write,'("Pmu: ",E17.10)') Pmu
!       write(output_unit_write,'("E_PHI_COL: ",E17.10)') E_PHI
       
       do cc=1_idef,pchunk
          if ((pm(cc).lt.min(cparams_ss%p_min*cparams_ss%pmin_scale, &
               p_therm)).and.flagCol(cc).eq.1_ip) then
!             write(output_unit_write,'("Momentum less than zero")')
             !             stop
!             write(output_unit_write,'("Particle not tracked at: ",E17.10," &
!                  & with xi: ",E17.10)') time*params%cpp%time, xi(cc)
             flagCol(cc)=0_ip
          end if
       end do

!       if (tt .EQ. 1_ip) then
!          write(output_unit_write,'("dp_rad: ",E17.10)') &
!               -gam(1)*pm(1)*(1-xi(1)*xi(1))/ &
!               (cparams_ss%taur/Bmag(1)**2)*dt
!          write(output_unit_write,'("dxi_rad: ",E17.10)') &
!               xi(1)*(1-xi(1)*xi(1))/ &
!               ((cparams_ss%taur/Bmag(1)**2)*gam(1))*dt
!       end if
       
!       if (tt .EQ. 1_ip) then
!          write(output_unit_write,'("CA: ",E17.10)') CAL(1)
!          write(output_unit_write,'("dCA: ",E17.10)') dCAL(1)
!          write(output_unit_write,'("CF ",E17.10)') CFL(1)
!          write(output_unit_write,'("CB: ",E17.10)') CBL(1)
!       end if

       
    end if
    
  end subroutine include_CoulombCollisions_GC_p

  subroutine include_CoulombCollisionsLA_GC_p(spp,achunk,tt,params, &
       Y_R,Y_PHI,Y_Z,Ppll,Pmu,me,flagCon,flagCol,F,P,E_PHI,ne,Te,PSIp)

    TYPE(SPECIES), INTENT(INOUT)    :: spp
    TYPE(PROFILES), INTENT(IN)                                 :: P
    TYPE(FIELDS), INTENT(IN)                                   :: F
    TYPE(KORC_PARAMS), INTENT(INOUT) 		:: params
    INTEGER, INTENT(IN) :: achunk
    REAL(rp), DIMENSION(achunk), INTENT(INOUT) 	:: Ppll
    REAL(rp), DIMENSION(achunk), INTENT(INOUT) 	:: Pmu
    REAL(rp), DIMENSION(achunk) 			:: Bmag
    REAL(rp), DIMENSION(achunk) 	:: B_R,B_PHI,B_Z
    REAL(rp), DIMENSION(achunk) :: curlb_R,curlb_PHI,curlb_Z
    REAL(rp), DIMENSION(achunk) :: gradB_R,gradB_PHI,gradB_Z,ntot
    REAL(rp), DIMENSION(achunk) 	:: E_R,E_Z,E_PHI_LAC
    REAL(rp), DIMENSION(achunk), INTENT(OUT) 	:: E_PHI,ne,Te,PSIp
    REAL(rp), DIMENSION(achunk), INTENT(IN) 			:: Y_R,Y_PHI,Y_Z
    INTEGER(is), DIMENSION(achunk), INTENT(INOUT) 	:: flagCol
    INTEGER(is), DIMENSION(achunk), INTENT(INOUT) 	:: flagCon
    REAL(rp), INTENT(IN) 			:: me
    REAL(rp), DIMENSION(achunk) 			:: Zeff
    REAL(rp), DIMENSION(achunk) 			:: nAr0,nAr1,nAr2,nAr3
    REAL(rp), DIMENSION(achunk) 			:: nD,nD1
    REAL(rp), DIMENSION(achunk,2) 			:: dW
    REAL(rp), DIMENSION(achunk,2) 			:: rnd1
    REAL(rp) 					:: dt,time
    REAL(rp), DIMENSION(achunk) 	:: pm,pm0
    REAL(rp), DIMENSION(achunk)  	:: dp
    REAL(rp), DIMENSION(achunk)  	:: xi,xi0
    REAL(rp), DIMENSION(achunk)  	:: dxi
    REAL(rp), DIMENSION(achunk)  					:: v,gam
    !! speed of particle
    REAL(rp), DIMENSION(achunk) 					:: CAL
    REAL(rp) , DIMENSION(achunk)					:: dCAL
    REAL(rp), DIMENSION(achunk) 					:: CFL
    REAL(rp), DIMENSION(achunk) 					:: CBL
    REAL(rp), DIMENSION(achunk) 	:: SC_p,SC_xi,BREM_p
    REAL(rp) 					:: kappa
    integer :: cc,ii
    integer(ip),INTENT(IN) :: tt
    REAL(rp), DIMENSION(achunk,params%num_impurity_species) 	:: nimp
  

    dt=cparams_ss%coll_per_dump_dt
    time=params%init_time+(params%it-1)*params%dt+ &
         tt*cparams_ss%coll_per_dump_dt


       

    if (params%field_eval.eq.'eqn') then
       call analytical_fields_GC_p(achunk,F,Y_R,Y_PHI, &
            Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
            gradB_R,gradB_PHI,gradB_Z,PSIp)          
    else if (params%field_eval.eq.'interp') then
#ifdef PSPLINE
       if (F%axisymmetric_fields) then
          if (F%Bflux) then
             if (.not.params%SC_E) then
                call calculate_GCfields_p(achunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                     E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                     gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp)
             else
                call calculate_GCfields_p_FS(achunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                     E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                     gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp)
             end if

          else if (F%ReInterp_2x1t) then
             call calculate_GCfieldswE_p(achunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                  E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                  gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp)
          else if (F%Bflux3D) then
             call calculate_GCfields_2x1t_p(achunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                  E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                  gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp,time)
          else if (F%dBfield) then
             call calculate_2DBdBfields_p(achunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                  E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                  gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp)
          else
             call interp_fields_p(achunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                  E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                  gradB_R,gradB_PHI,gradB_Z,flagCon)
          end if
       else
          if (F%dBfield) then
             call calculate_2DBdBfields_p(achunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                  E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                  gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp)
          else
             call interp_fields_3D_p(achunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, &
                  E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, &
                  gradB_R,gradB_PHI,gradB_Z,flagCon)
          end if
       endif
#endif
       if(.not.F%ReInterp_2x1t) call add_analytical_E_p(params,tt,F,E_PHI,Y_R,Y_Z)
    end if


    if (params%profile_model(1:10).eq.'ANALYTICAL') then
       call analytical_profiles_p(achunk,time,params,Y_R,Y_Z,P,F, &
            ne,Te,Zeff,PSIp)
    else if (params%profile_model(1:8).eq.'EXTERNAL') then
#ifdef PSPLINE
       if (params%profile_model(10:10).eq.'H') then
          call interp_Hcollision_p(achunk,Y_R,Y_PHI,Y_Z,ne,Te,Zeff, &
               nAr0,nAr1,nAr2,nAr3,nD,nD1,flagCon)
          do cc=1_idef,achunk
             nimp(cc,1)=nAr0(cc)
             nimp(cc,2)=nAr1(cc)
             nimp(cc,3)=nAr2(cc)
             nimp(cc,4)=nAr3(cc)
             nimp(cc,5)=nD(cc)
             nimp(cc,6)=nD1(cc)
          end do
       else
          call interp_FOcollision_p(achunk,Y_R,Y_PHI,Y_Z,ne,Te,Zeff,flagCon)
       endif
#endif
    end if

    E_PHI_LAC=E_PHI
    if (.not.params%FokPlan) E_PHI=0._rp

    !$OMP SIMD
    !       !$OMP& aligned (pm,xi,v,Ppll,Bmag,Pmu)
    do cc=1_idef,achunk
       Bmag(cc)=sqrt(B_R(cc)*B_R(cc)+B_PHI(cc)*B_PHI(cc)+B_Z(cc)*B_Z(cc))
       ! Transform p_pll,mu to P,eta
       pm(cc) = SQRT(Ppll(cc)*Ppll(cc)+2*me*Bmag(cc)*Pmu(cc))
       pm0(cc)=pm(cc)
       xi(cc) = Ppll(cc)/pm(cc)
       xi0(cc)=xi(cc)
       
       gam(cc) = sqrt(1+pm(cc)*pm(cc))

       v(cc) = pm(cc)/gam(cc)
       ! normalized speed (v_K=v_P/c)
    end do
    !$OMP END SIMD

    !       write(output_unit_write,'("ne: "E17.10)') ne
    !       write(output_unit_write,'("Te: "E17.10)') Te
    !       write(output_unit_write,'("Bmag: "E17.10)') Bmag                
    !       write(output_unit_write,'("v: ",E17.10)') v
    !       write(output_unit_write,'("xi: ",E17.10)') xi
    !       write(output_unit_write,'("size(E_PHI_GC): ",I16)') size(E_PHI)


    !$OMP SIMD
    !       !$OMP& aligned(rnd1,dW,CAL,dCAL,CFL,CBL,v,ne,Te,Zeff,dp, &
    !       !$OMP& flagCon,flagCol,dxi,xi,pm,Ppll,Pmu,Bmag)
    do cc=1_idef,achunk

#ifdef PARALLEL_RANDOM
       rnd1(cc,1) = get_random()
       rnd1(cc,2) = get_random()
       !       rnd1(:,1) = get_random_mkl()
       !       rnd1(:,2) = get_random_mkl()
#else
       call RANDOM_NUMBER(rnd1)
#endif

       dW(cc,1) = SQRT(3*dt)*(-1+2*rnd1(cc,1))     
       dW(cc,2) = SQRT(3*dt)*(-1+2*rnd1(cc,2))     

       !          write(output_unit_write,'("dW1: ",E17.10)') dW(cc,1)
       !          write(output_unit_write,'("dW2: ",E17.10)') dW(cc,2)

       if (params%profile_model(10:10).eq.'H') then
          CAL(cc) = CA_SD(v(cc),ne(cc),Te(cc))
          dCAL(cc)= dCA_SD(v(cc),me,ne(cc),Te(cc))
          CFL(cc) = CF_SD_FIO(params,v(cc),ne(cc),Te(cc),nimp(cc,:))
          CBL(cc) = (CB_ee_SD(v(cc),ne(cc),Te(cc),Zeff(cc))+ &
               CB_ei_SD_FIO(params,v(cc),ne(cc),Te(cc),nimp(cc,:),Zeff(cc)))
          ! using *_FIO routine to include additions due to Hollmann species
          ! profile
       else
          CAL(cc) = CA_SD(v(cc),ne(cc),Te(cc))
          dCAL(cc)= dCA_SD(v(cc),me,ne(cc),Te(cc))
          CFL(cc) = CF_SD(params,v(cc),ne(cc),Te(cc))
          CBL(cc) = (CB_ee_SD(v(cc),ne(cc),Te(cc),Zeff(cc))+ &
               CB_ei_SD(params,v(cc),ne(cc),Te(cc),Zeff(cc)))
       endif

       if (.not.energy_diffusion) then
          CAL(cc)=0._rp
          dCAL(cc)=0._rp
       endif

       if (.not.pitch_diffusion) then
          CBL(cc)=0._rp
       endif


       dp(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
            ((-CFL(cc)+dCAL(cc)+E_PHI(cc)*xi(cc))*dt+ &
            sqrt(2.0_rp*CAL(cc))*dW(cc,1))

       dxi(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
            ((-2*xi(cc)*CBL(cc)/(pm(cc)*pm(cc))+ &
            E_PHI(cc)*(1-xi(cc)*xi(cc))/pm(cc))*dt- &
            sqrt(2.0_rp*CBL(cc)*(1-xi(cc)*xi(cc)))/pm(cc)*dW(cc,2))


       if(cparams_ss%sample_test) then
          dp(cc)=0._rp
          dxi(cc)=0._rp
       end if

       !          write(output_unit_write,'("dp: ",E17.10)') dp(cc)
       !          write(output_unit_write,'("dxi: ",E17.10)') dxi(cc)

       !write(6,*) 'gam,xi',gam(cc),xi(cc)
       
       !write(6,*) 'dpE',E_PHI(cc)*xi(cc)*dt
       !write(6,*) 'dpCF',CFL(cc)*dt
       !write(6,*) 'dpCA',sqrt(2*CAL(cc)*dt)

       !write(6,*) 'dxiE',E_PHI(cc)*(1-xi(cc)*xi(cc))/pm(cc)*dt
       !write(6,*) 'dxiCB',2*xi(cc)*CBL(cc)/(pm(cc)*pm(cc))*dt
       
    end do
    !$OMP END SIMD

    if (params%FokPlan.and.params%radiation) then
       if(params%GC_rad_model.eq.'SDE') then

          !$OMP SIMD
          do cc=1_idef,achunk

             SC_p(cc)=-gam(cc)*pm(cc)*(1-xi(cc)*xi(cc))/ &
                  (cparams_ss%taur/Bmag(cc)**2)
             SC_xi(cc)=xi(cc)*(1-xi(cc)*xi(cc))/ &
                  ((cparams_ss%taur/Bmag(cc)**2)*gam(cc))

             kappa=2._rp*C_PI*C_RE**2._rp*C_ME*C_C**2._rp/ &
                  (params%cpp%length**2._rp*params%cpp%energy)
             BREM_p(cc)=-2._rp*ne(cc)*kappa*Zeff(cc)*(Zeff(cc)+1._rp)* &
                  C_a/C_PI*(gam(cc)-1._rp)*(log(2._rp*gam(cc))-1._rp/3._rp)

             !write(6,*) 'dpR',SC_p(cc)*dt
             !write(6,*) 'dpB',BREM_p(cc)*dt

             !write(6,*) 'dxiR',SC_xi(cc)*dt

             if (.not.FP_bremsstrahlung) BREM_p(cc)=0._rp
             
             dp(cc)=dp(cc)+(SC_p(cc)+BREM_p(cc))*dt* &
                  REAL(flagCol(cc))*REAL(flagCon(cc))
             dxi(cc)=dxi(cc)+(SC_xi(cc))*dt* &
                  REAL(flagCol(cc))*REAL(flagCon(cc))

          end do
          !$OMP END SIMD

       end if
    end if

    !$OMP SIMD
    do cc=1_idef,achunk  

       pm(cc)=pm(cc)+dp(cc)
       xi(cc)=xi(cc)+dxi(cc)
    end do
    !$OMP END SIMD

    do cc=1_idef,achunk  
       !          if (pm(cc)<0) pm(cc)=-pm(cc)

       ! Keep xi between [-1,1]
       if (xi(cc)>1) then
          !             write(output_unit_write,'("High xi at: ",E17.10," with dxi: ",E17.10)') &
          !                  time*params%cpp%time, dxi(cc)
          xi(cc)=1-mod(xi(cc),1._rp)
       else if (xi(cc)<-1) then
          xi(cc)=-1-mod(xi(cc),-1._rp)
          !             write(output_unit_write,'("Low xi at: ",E17.10," with dxi: ",E17.10)') &
          !                  time*params%cpp%time, dxi(cc)
       endif

       if ((pm(cc).lt.min(cparams_ss%p_min*cparams_ss%pmin_scale, &
            p_therm)).and.flagCol(cc).eq.1_ip) then
          !             write(output_unit_write,'("Momentum less than zero")')
          !             stop
          !             write(output_unit_write,'("Particle not tracked at: ",E17.10," &
          !                  & with xi: ",E17.10)') time*params%cpp%time, xi(cc)
          flagCol(cc)=0_ip
       end if

    end do


    !       write(output_unit_write,'("rnd1: ",E17.10)') rnd1
    !       write(output_unit_write,'("flag: ",I16)') flag
    !       write(output_unit_write,'("CA: ",E17.10)') CAL
    !       write(output_unit_write,'("dCA: ",E17.10)') dCAL
    !       write(output_unit_write,'("CF ",E17.10)') CFL
    !       write(output_unit_write,'("CB: ",E17.10)') CBL
    !       write(output_unit_write,'("dp: ",E17.10)') dp
    !       write(output_unit_write,'("dxi: ",E17.10)') dxi
    !       write(output_unit_write,'("Ppll: ",E17.10)') Ppll
    !      write(output_unit_write,'("Pmu: ",E17.10)') Pmu
    !       write(output_unit_write,'("E_PHI_COL: ",E17.10)') E_PHI


    !       if (tt .EQ. 1_ip) then
    !          write(output_unit_write,'("dp_rad: ",E17.10)') &
    !               -gam(1)*pm(1)*(1-xi(1)*xi(1))/ &
    !               (cparams_ss%taur/Bmag(1)**2)*dt
    !          write(output_unit_write,'("dxi_rad: ",E17.10)') &
    !               xi(1)*(1-xi(1)*xi(1))/ &
    !               ((cparams_ss%taur/Bmag(1)**2)*gam(1))*dt
    !       end if

    !       if (tt .EQ. 1_ip) then
    !          write(output_unit_write,'("CA: ",E17.10)') CAL(1)
    !          write(output_unit_write,'("dCA: ",E17.10)') dCAL(1)
    !          write(output_unit_write,'("CF ",E17.10)') CFL(1)
    !          write(output_unit_write,'("CB: ",E17.10)') CBL(1)
    !       end if

#if DBG_CHECK    
    do cc=1_idef,achunk  
       if (ISNAN(xi(cc)).or.(abs(xi(cc)).gt.1._rp)) then
          write(6,*) 'xi is NaN or >1 before LAC'
          write(6,*) 'p0,xi0',pm0(cc),xi0(cc)
          write(6,*) 'p,xi',pm(cc),xi(cc)
          write(6,*) 'dp,dxi',dp(cc),dxi(cc)
          write(6,*) 'CBL',CBL(cc)
          write(6,*) 'v,ne,Te,Zeff',v(cc),ne(cc)*params%cpp%density,Te(cc)*params%cpp%temperature,Zeff(cc)
          write(6,*) 'ppll,pmu,Bmag',Ppll(cc),Pmu(cc),Bmag(cc)
          call korc_abort(24)
       end if
    end do
# endif
    
    if (cparams_ss%avalanche) then 

       !$OMP SIMD
       do cc=1_idef,achunk
          ntot(cc)=ne(cc)
          if (params%bound_electron_model.eq.'HESSLOW') then          

             if ((cparams_ms%Zj(1).eq.0.0).and. &
                  (neut_prof.eq.'UNIFORM')) then
                ntot(cc)=ntot(cc)+cparams_ms%nz(1)* &
                     (cparams_ms%Zo(1)-cparams_ms%Zj(1))
             else if ((cparams_ms%Zj(1).eq.0.0).and. &
                  (neut_prof.eq.'HOLLOW')) then
                ntot(cc)=ntot(cc)+max(cparams_ms%nz(1)-ne(cc),0._rp)* &
                     (cparams_ms%Zo(1)-cparams_ms%Zj(1))
             else
                ntot(cc)=ntot(cc)+ne(cc)*cparams_ms%nz(1)/cparams_ms%ne* &
                     (cparams_ms%Zo(1)-cparams_ms%Zj(1))
             endif

             do ii=2,cparams_ms%num_impurity_species
                ntot(cc)=ntot(cc)+ne(cc)*cparams_ms%nz(ii)/cparams_ms%ne* &
                     (cparams_ms%Zo(ii)-cparams_ms%Zj(ii))
             end do

          end if
       end do
       !$OMP END SIMD

       !write(6,*) 'ntot',ntot*params%cpp%density

       call large_angle_source(spp,params,achunk,F,Y_R,Y_PHI,Y_Z, &
            pm,xi,ne,ntot,Te,Bmag,E_PHI_LAC,me,flagCol,flagCon)

    end if

#if DBG_CHECK    
    do cc=1_idef,achunk  
       if (ISNAN(xi(cc)).or.(abs(xi(cc)).gt.1._rp)) then
          write(6,*) 'xi is NaN or >1 after LAC'
          write(6,*) 'p0,xi0',pm0(cc),xi0(cc)
          write(6,*) 'p,xi',pm(cc),xi(cc)
          write(6,*) 'dp,dxi',dp(cc),dxi(cc)
          write(6,*) 'CBL',CBL(cc)
          write(6,*) 'v,ne,Te,Zeff',v(cc),ne(cc)*params%cpp%density,Te(cc)*params%cpp%temperature,Zeff(cc)
          call korc_abort(24)
       end if
    end do
# endif
    
    !$OMP SIMD
    do cc=1_idef,achunk  
       ! Transform P,xi to p_pll,mu
       Ppll(cc)=pm(cc)*xi(cc)
       Pmu(cc)=(pm(cc)*pm(cc)-Ppll(cc)*Ppll(cc))/(2*me*Bmag(cc))
    end do
    !$OMP END SIMD

#if DBG_CHECK    
    do cc=1_idef,achunk
       if (Pmu(cc).lt.0._rp) then
          write(6,*) 'mu is negative'
          write(6,*) 'p,xi',pm(cc),xi(cc)
          write(6,*) 'V_PLL,V_MU',Ppll(cc),Pmu(cc)
          call korc_abort(24)
       endif
    end do
#endif

    E_PHI=E_PHI_LAC
    
  end subroutine include_CoulombCollisionsLA_GC_p

#ifdef FIO
  subroutine include_CoulombCollisions_GCfio_p(tt,params,Y_R,Y_PHI,Y_Z, &
       Ppll,Pmu,me,flagCon,flagCol,F,P,E_PHI,ne,ni,Te,Zeff,nimp,PSIp,hint)

    TYPE(PROFILES), INTENT(IN)                                 :: P
    TYPE(FIELDS), INTENT(IN)                                   :: F
    TYPE(KORC_PARAMS), INTENT(INOUT) 		:: params
    REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) 	:: Ppll
    REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) 	:: Pmu
    REAL(rp), DIMENSION(params%pchunk) 			:: Bmag
    REAL(rp), DIMENSION(params%pchunk) 	:: B_R,B_PHI,B_Z
    REAL(rp), DIMENSION(params%pchunk) :: curlb_R,curlb_PHI,curlb_Z
    REAL(rp), DIMENSION(params%pchunk) :: gradB_R,gradB_PHI,gradB_Z
    REAL(rp), DIMENSION(params%pchunk) 	:: E_R,E_Z
    REAL(rp), DIMENSION(params%pchunk) 	:: E_PHI,PSIp,E_PHI0
    REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) 	:: ne,Te,ni
    REAL(rp), DIMENSION(params%pchunk,params%num_impurity_species),&
         & INTENT(INOUT) 	:: nimp
    REAL(rp), DIMENSION(params%pchunk), INTENT(IN) 	:: Y_R,Y_PHI&
         &,Y_Z
    INTEGER(is), DIMENSION(params%pchunk), INTENT(INOUT)  :: flagCol
    INTEGER(is), DIMENSION(params%pchunk), INTENT(INOUT)  :: flagCon
    TYPE(C_PTR), DIMENSION(params%pchunk), INTENT(INOUT)  :: hint
    REAL(rp), INTENT(IN) 			:: me
    REAL(rp), DIMENSION(params%pchunk), INTENT(OUT) 	:: Zeff
    REAL(rp), DIMENSION(params%pchunk,2) 			:: dW
    REAL(rp), DIMENSION(params%pchunk,2) 			:: rnd1
    REAL(rp) 					:: dt,time
    REAL(rp), DIMENSION(params%pchunk) 	:: pm
    REAL(rp), DIMENSION(params%pchunk)  :: dp
    REAL(rp), DIMENSION(params%pchunk)  :: xi
    REAL(rp), DIMENSION(params%pchunk)  :: dxi
    REAL(rp), DIMENSION(params%pchunk)  :: v,gam
    !! speed of particle
    REAL(rp), DIMENSION(params%pchunk) 	:: CAL
    REAL(rp) , DIMENSION(params%pchunk)	:: dCAL
    REAL(rp), DIMENSION(params%pchunk) 	:: CFL
    REAL(rp), DIMENSION(params%pchunk) 	:: CBL
    REAL(rp), DIMENSION(params%pchunk) 	:: SC_p,SC_mu,BREM_p
    REAL(rp) 					:: kappa
    integer :: cc,pchunk,ii
    integer(ip),INTENT(IN) :: tt

    pchunk=params%pchunk
    
    if (MODULO(params%it+tt,cparams_ss%subcycling_iterations) .EQ. 0_ip) then
       dt = REAL(cparams_ss%subcycling_iterations,rp)*params%dt       

       call get_fio_GCmagnetic_fields_p(params,F,Y_R,Y_PHI,Y_Z, &
            B_R,B_PHI,B_Z,gradB_R,gradB_PHI,gradB_Z, &
            curlb_R,curlb_PHI,curlb_Z,flagCon,hint)

       if (F%FIO_E .ge. 0) then
          call get_fio_GCelectric_fields_p(params,F, &
               Y_R,Y_PHI,Y_Z,E_R,E_PHI,E_Z,flagCon,hint)
       end if
       call get_fio_vector_potential_p(params,F,Y_R,Y_PHI,Y_Z, &
            PSIp,flagCon,hint)

       call get_fio_profile_p(params,P,Y_R,Y_PHI,Y_Z, &
            ne,Te,flagCon,hint)

       call get_fio_ion_p(params,P,Y_R,Y_PHI,Y_Z, &
            ne,ni,nimp,Zeff,flagCon,hint)

       
       !write(6,*) ne,Te,nimp,Zeff
       
       !$OMP SIMD
!       !$OMP& aligned (pm,xi,v,Ppll,Bmag,Pmu)
       do cc=1_idef,pchunk
          Bmag(cc)=sqrt(B_R(cc)*B_R(cc)+B_PHI(cc)*B_PHI(cc)+B_Z(cc)*B_Z(cc))
          ! Transform p_pll,mu to P,eta
          pm(cc) = SQRT(Ppll(cc)*Ppll(cc)+2*me*Bmag(cc)*Pmu(cc))
          xi(cc) = Ppll(cc)/pm(cc)

          gam(cc) = sqrt(1+pm(cc)*pm(cc))
          
          v(cc) = pm(cc)/gam(cc)
          ! normalized speed (v_K=v_P/c)
             
          E_PHI0(cc)=E_PHI(cc)
       end do
       !$OMP END SIMD

       !write(6,*) 'R',Y_R*params%cpp%length
       !write(6,*) 'PHI',Y_PHI
       !write(6,*) 'Z',Y_Z*params%cpp%length
       !write(6,*) 'ne',ne*params%cpp%density
       !write(6,*) 'ni',ni*params%cpp%density
       !write(6,*) 'nimp',nimp(:,1:2)*params%cpp%density
       !write(6,*) 'Zeff',Zeff
       
       if (.not.params%FokPlan) E_PHI=0._rp

!       write(output_unit_write,'("ne: "E17.10)') ne
!       write(output_unit_write,'("Te: "E17.10)') Te
!       write(output_unit_write,'("Bmag: "E17.10)') Bmag                
!       write(output_unit_write,'("v: ",E17.10)') v
!       write(output_unit_write,'("xi: ",E17.10)') xi
       !       write(output_unit_write,'("size(E_PHI_GC): ",I16)') size(E_PHI)


       !$OMP SIMD
!       !$OMP& aligned(rnd1,dW,CAL,dCAL,CFL,CBL,v,ne,Te,Zeff,dp, &
!       !$OMP& flagCon,flagCol,dxi,xi,pm,Ppll,Pmu,Bmag)
       do cc=1_idef,pchunk
       
#ifdef PARALLEL_RANDOM
          rnd1(cc,1) = get_random()
          rnd1(cc,2) = get_random()
          !       rnd1(:,1) = get_random_mkl()
          !       rnd1(:,2) = get_random_mkl()
#else
          call RANDOM_NUMBER(rnd1)
#endif
          
          dW(cc,1) = SQRT(3*dt)*(-1+2*rnd1(cc,1))     
          dW(cc,2) = SQRT(3*dt)*(-1+2*rnd1(cc,2))     

!          write(output_unit_write,'("dW1: ",E17.10)') dW(cc,1)
!          write(output_unit_write,'("dW2: ",E17.10)') dW(cc,2)
          
          CAL(cc) = CA_SD(v(cc),ne(cc),Te(cc))
          dCAL(cc)= dCA_SD(v(cc),me,ne(cc),Te(cc))
          CFL(cc) = CF_SD_FIO(params,v(cc),ne(cc),Te(cc),nimp(cc,:))
          CBL(cc) = (CB_ee_SD(v(cc),ne(cc),Te(cc),Zeff(cc))+ &
               CB_ei_SD_FIO(params,v(cc),ne(cc),Te(cc),nimp(cc,:),Zeff(cc)))
          
          
          dp(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
               ((-CFL(cc)+dCAL(cc)+E_PHI(cc)*xi(cc))*dt+ &
               sqrt(2.0_rp*CAL(cc))*dW(cc,1))

          dxi(cc)=REAL(flagCol(cc))*REAL(flagCon(cc))* &
               ((-2*xi(cc)*CBL(cc)/(pm(cc)*pm(cc))+ &
               E_PHI(cc)*(1-xi(cc)*xi(cc))/pm(cc))*dt- &
               sqrt(2.0_rp*CBL(cc)*(1-xi(cc)*xi(cc)))/pm(cc)*dW(cc,2))

!          write(output_unit_write,'("dp: ",E17.10)') dp(cc)
!          write(output_unit_write,'("dxi: ",E17.10)') dxi(cc)

       end do
       !$OMP END SIMD
          
       if (params%FokPlan.and.params%radiation) then
          if(params%GC_rad_model.eq.'SDE') then

             !$OMP SIMD
             do cc=1_idef,pchunk

                SC_p(cc)=-gam(cc)*pm(cc)*(1-xi(cc)*xi(cc))/ &
                     (cparams_ss%taur/Bmag(cc)**2)
                SC_mu(cc)=xi(cc)*(1-xi(cc)*xi(cc))/ &
                     ((cparams_ss%taur/Bmag(cc)**2)*gam(cc))

                kappa=2._rp*C_PI*C_RE**2._rp*C_ME*C_C**2._rp
                BREM_p(cc)=-2._rp*ne(cc)*kappa*Zeff(cc)*(Zeff(cc)+1._rp)* &
                     C_a/C_PI*(gam(cc)-1._rp)*(log(2._rp*gam(cc))-1._rp/3._rp)


                dp(cc)=dp(cc)+(SC_p(cc)+BREM_p(cc))*dt* &
                     REAL(flagCol(cc))*REAL(flagCon(cc))
                dxi(cc)=dxi(cc)+(SC_mu(cc))*dt* &
                     REAL(flagCol(cc))*REAL(flagCon(cc))

             end do
             !$OMP END SIMD

          end if
       end if

       !$OMP SIMD
       do cc=1_idef,pchunk  

          pm(cc)=pm(cc)+dp(cc)
          xi(cc)=xi(cc)+dxi(cc)

!          if (pm(cc)<0) pm(cc)=-pm(cc)

          ! Keep xi between [-1,1]
          if (xi(cc)>1) then
!             write(output_unit_write,'("High xi at: ",E17.10," with dxi: ",E17.10)') &
!                  time*params%cpp%time, dxi(cc)
             xi(cc)=1-mod(xi(cc),1._rp)
          else if (xi(cc)<-1) then
             xi(cc)=-1-mod(xi(cc),-1._rp)
!             write(output_unit_write,'("Low xi at: ",E17.10," with dxi: ",E17.10)') &
!                  time*params%cpp%time, dxi(cc)
          endif

          ! Transform P,xi to p_pll,mu
          Ppll(cc)=pm(cc)*xi(cc)
          Pmu(cc)=(pm(cc)*pm(cc)-Ppll(cc)*Ppll(cc))/(2*me*Bmag(cc))
       end do
       !$OMP END SIMD

#if DBG_CHECK    
       do cc=1_idef,pchunk
          if((isnan(Ppll(cc)).or.isnan(Pmu(cc))).and. &
             ((flagCol(cc).eq.1_is).and.(flagCon(cc).eq.1_is))) then
             write(6,*) 'End collision'
             write(6,*) 'Ppll',Ppll(cc)
             write(6,*) 'Pmu',Pmu(cc)
             write(6,*) 'Bmag',Bmag(cc)
             write(6,*) 'pm',pm(cc)
             write(6,*) 'xi',xi(cc)
             write(6,*) 'dp',dp(cc)
             write(6,*) 'dxi',dxi(cc)
             write(6,*) 'CFL',CFL(cc)
             write(6,*) 'CBL',CBL(cc)
             write(6,*) 'dCAL',dCAL(cc)
             write(6,*) 'CAL',CAL(cc)
             write(6,*) 'v',v(cc)
             write(6,*) 'ne',ne(cc)
             write(6,*) 'Te',Te(cc)
             write(6,*) 'nimp',nimp(cc,:)
             write(6,*) 'Zeff',Zeff(cc)
             write(6,*) 'Y_R',Y_R(cc)
             write(6,*) 'Y_PHI',Y_PHI(cc)
             write(6,*) 'Y_Z',Y_Z(cc)
             
             stop 'Ppll or Pmu is NaN'
          endif
       end do
#endif
       
!       write(output_unit_write,'("rnd1: ",E17.10)') rnd1
!       write(output_unit_write,'("flag: ",I16)') flag
!       write(output_unit_write,'("CA: ",E17.10)') CAL
!       write(output_unit_write,'("dCA: ",E17.10)') dCAL
!       write(output_unit_write,'("CF ",E17.10)') CFL
!       write(output_unit_write,'("CB: ",E17.10)') CBL
!       write(output_unit_write,'("dp: ",E17.10)') dp
!       write(output_unit_write,'("dxi: ",E17.10)') dxi
!       write(output_unit_write,'("Ppll: ",E17.10)') Ppll
!      write(output_unit_write,'("Pmu: ",E17.10)') Pmu
!       write(output_unit_write,'("E_PHI_COL: ",E17.10)') E_PHI
       
       do cc=1_idef,pchunk
          if ((pm(cc).lt.min(cparams_ss%p_min*cparams_ss%pmin_scale, &
               p_therm)).and.flagCol(cc).eq.1_ip) then
!             write(output_unit_write,'("Momentum less than zero")')
             !             stop
!             write(output_unit_write,'("Particle not tracked at: ",E17.10," &
!                  & with xi: ",E17.10)') time*params%cpp%time, xi(cc)
             flagCol(cc)=0_ip
          end if
       end do

!       if (tt .EQ. 1_ip) then
!          write(output_unit_write,'("dp_rad: ",E17.10)') &
!               -gam(1)*pm(1)*(1-xi(1)*xi(1))/ &
!               (cparams_ss%taur/Bmag(1)**2)*dt
!          write(output_unit_write,'("dxi_rad: ",E17.10)') &
!               xi(1)*(1-xi(1)*xi(1))/ &
!               ((cparams_ss%taur/Bmag(1)**2)*gam(1))*dt
!       end if
       
!       if (tt .EQ. 1_ip) then
!          write(output_unit_write,'("CA: ",E17.10)') CAL(1)
!          write(output_unit_write,'("dCA: ",E17.10)') dCAL(1)
!          write(output_unit_write,'("CF ",E17.10)') CFL(1)
!          write(output_unit_write,'("CB: ",E17.10)') CBL(1)
!       end if

       if (.not.params%FokPlan) E_PHI=E_PHI0
       
    end if
    
  end subroutine include_CoulombCollisions_GCfio_p
#endif

  subroutine large_angle_source(spp,params,achunk,F,Y_R,Y_PHI,Y_Z, &
       pm,xi,ne,netot,Te,Bmag,E_PHI,me,flagCol,flagCon)
    TYPE(SPECIES), INTENT(INOUT)    :: spp
    TYPE(KORC_PARAMS), INTENT(IN) 			:: params
    TYPE(FIELDS), INTENT(IN)                                   :: F
    INTEGER, INTENT(IN) :: achunk
    REAL(rp), INTENT(INOUT), DIMENSION(achunk)  :: pm,xi
    REAL(rp), INTENT(IN), DIMENSION(achunk)  :: Y_R,Y_PHI,Y_Z
    REAL(rp), INTENT(IN), DIMENSION(achunk)  :: ne,netot,Te
    REAL(rp), INTENT(IN), DIMENSION(achunk)  :: Bmag,E_PHI
    INTEGER(is), INTENT(IN), DIMENSION(achunk)  :: flagCol,flagCon
    REAL(rp), INTENT(IN)  :: me
    REAL(rp), DIMENSION(achunk)  :: gam,prob0,prob1
    REAL(rp) :: gam_min,p_min,gammax,dt,gamsecmax,psecmax,ptrial
    REAL(rp) :: gamtrial,cosgam1,xirad,xip,xim,xitrial,sinsq1,cossq1,pitchprob1
    REAL(rp) :: dsigdgam1,S_LAmax,S_LA1,tmppm,gamvth,vmin,E_C,p_c,gam_c,pRE
    INTEGER :: ngam1,neta1
    INTEGER :: ii,jj,cc,seciter
    REAL(rp), DIMENSION(cparams_ss%ngrid1) :: gam1,pm1,tmpgam1,tmpcosgam,tmpdsigdgam,tmpsecthreshgam,probtmp,intpitchprob
    REAL(rp), DIMENSION(cparams_ss%ngrid1-1) :: dpm1
    REAL(rp), DIMENSION(cparams_ss%ngrid1) :: eta1,tmpsinsq,tmpcossq
    REAL(rp), DIMENSION(cparams_ss%ngrid1-1) :: deta1
    REAL(rp), DIMENSION(cparams_ss%ngrid1,cparams_ss%ngrid1) :: cosgam,sinsq,cossq,tmpcossq1,pitchprob,dsigdgam
    REAL(rp), DIMENSION(cparams_ss%ngrid1,cparams_ss%ngrid1) :: secthreshgam,pm11,gam11,eta11,S_LA,pitchrad
    LOGICAL :: accepted


    dt=cparams_ss%coll_per_dump_dt*params%cpp%time
    ngam1=cparams_ss%ngrid1
    neta1=cparams_ss%ngrid1

    
    !$OMP SIMD
    do cc=1_idef,achunk
       gam(cc) = sqrt(1+pm(cc)*pm(cc))       

#ifdef PARALLEL_RANDOM
       prob0(cc) = get_random()
#else
       call RANDOM_NUMBER(prob0)
#endif
       
    end do
    !$OMP END SIMD

    vmin=1/sqrt(1+1/(cparams_ss%p_min*cparams_ss%pmin_scale)**2)
    
    !! For each primary RE, calculating probability to generate a secondary RE
    
    do cc=1_idef,achunk

       E_C=Gammacee(vmin,netot(cc),Te(cc))

       !write(6,*) 'E',E_PHI*params%cpp%Eo
       !write(6,*) 'E_C',E_C*params%cpp%Eo
       !write(6,*) 'E_c,min',cparams_ms%Ec_min*params%cpp%Eo
       !write(6,*) 'ne',ne(cc)*params%cpp%density
       !write(6,*) 'netot',netot(cc)*params%cpp%density
       !write(6,*) 'Te',Te(cc)*params%cpp%temperature
       !write(6,*) 'Clog',CLogee_wu(params,ne(cc)*params%cpp%density,Te(cc)*params%cpp%temperature)

       if (E_C.gt.abs(E_PHI(cc))) cycle
       
       p_c=cparams_ss%pmin_scale/sqrt(abs(E_PHI(cc))/E_C-1)
       gam_c=sqrt(1+p_c**2)

       if(cparams_ss%min_secRE.eq.'THERM') then
          gam_min=(gam_c+1)/2
          p_min=sqrt(gam_min**2-1)
       else
          gam_min=gam_c
          p_min=p_c
       end if

       gammax=(gam(cc)+1._rp)/2._rp

       if (gam_min.eq.1._rp) then
          write(6,*) 'R',Y_R(cc)*params%cpp%length,'Z',Y_Z(cc)*params%cpp%length
          write(6,*) 'vmin',vmin,'netot',netot(cc)*params%cpp%density,'Te',Te(cc)*params%cpp%temperature/C_E
          write(6,*) 'E',E_PHI*params%cpp%Eo,'E_c',E_C*params%cpp%Eo          
          write(6,*) 'p_c',p_c,'gam_c',gam_c
          write(6,*) 'p_min',p_min,'gam_min',gam_min
          !write(6,*) 'LAC_gam_resolution: ',TRIM(cparams_ss%LAC_gam_resolution)
          !write(6,*) 'gam_min,gammax',gam_min,gammax
       end if
       
       !! Generating 1D and 2D ranges for secondary RE distribution

       if (TRIM(cparams_ss%LAC_gam_resolution).eq.'LIN') then
          do ii=1,ngam1
             gam1(ii)=gam_min+(gammax-gam_min)* &
                  REAL(ii-1)/REAL(ngam1-1)
          end do
       elseif (TRIM(cparams_ss%LAC_gam_resolution).eq.'EXP') then
          do ii=1,ngam1
             tmpgam1(ii)=log10(gam_min)+ &
                  (log10(gammax)-log10(gam_min))* &
                  REAL(ii-1)/REAL(ngam1-1)
          end do
          gam1=10**(tmpgam1)
       elseif (TRIM(cparams_ss%LAC_gam_resolution).eq.'2EXP') then
          do ii=1,ngam1
             tmpgam1(ii)=log10(log10(gam_min))+ &
                  (log10(log10(gammax))-log10(log10(gam_min)))* &
                  REAL(ii-1)/REAL(ngam1-1)
          end do
          gam1=10**(10**(tmpgam1))
       end if

       !write(6,*) 'tmpgam1',tmpgam1
       !write(6,*) 'gam1',gam1


       pm1=sqrt(gam1**2-1)

       do ii=1,ngam1-1
          dpm1(ii)=pm1(ii+1)-pm1(ii)
       end do

       do ii=1,neta1
          eta1(ii)=C_PI*(ii-1)/(neta1-1)
       end do

       !write(6,*) 'eta1',eta1

       do ii=1,neta1-1
          deta1(ii)=eta1(ii+1)-eta1(ii)
       end do

       do ii=1,neta1
          pm11(:,ii)=pm1
          gam11(:,ii)=gam1
       end do

       do ii=1,ngam1
          eta11(ii,:)=eta1
       end do

       
       tmpcosgam=sqrt(((gam(cc)+1)*(gam1-1))/((gam(cc)-1)*(gam1+1)))
       tmpdsigdgam=2*C_PI*C_RE**2/(gam(cc)**2-1)* &
            (((gam(cc)-1)**2*gam(cc)**2)/((gam1-1)**2*(gam(cc)-gam1)**2)- &
            (2*gam(cc)**2+2*gam(cc)-1)/((gam1-1)*(gam(cc)-gam1))+1)
       tmpsecthreshgam=1._rp
       where(gam1.gt.(gam(cc)+1)/2._rp) tmpsecthreshgam=0._rp

       !write(6,*) 'tmpcosgam',tmpcosgam
       !write(6,*) 'tmpdsigdgam',tmpdsigdgam
       !write(6,*) 'tmpsecthreshgam',tmpsecthreshgam
       
       
       do ii=1,neta1
          cosgam(:,ii)=tmpcosgam
          dsigdgam(:,ii)=tmpdsigdgam
          secthreshgam(:,ii)=tmpsecthreshgam
       end do

       !if (cc.eq.1) then
          !write(6,*) cosgam
       !end if
       
       tmpsinsq=(1-xi(cc)**2)*sin(eta1)**2
       tmpcossq=xi(cc)*cos(eta1)

       do ii=1,ngam1
          sinsq(ii,:)=tmpsinsq
          tmpcossq1(ii,:)=tmpcossq
       end do

       !if (cc.eq.1) then
          !write(6,*) sinsq
       !end if
       
       cossq=(cosgam-tmpcossq1)**2

       pitchrad=sinsq-cossq
       where(pitchrad.lt.0) pitchrad=tiny(0._rp)

       !if (cc.eq.1) then
          !write(6,*) cossq
          !write(6,*) 'sinsq-cossq',sqrt(sinsq-cossq)
          !write(6,*) 'pitchrad',pitchrad
       !end if
       
       pitchprob=1/(C_PI*sqrt(pitchrad))

       where(pitchprob.eq.1/(C_PI*sqrt(tiny(0._rp)))) pitchprob=0._rp

       !if (cc.eq.1) then
          !write(6,*) 'pitchprob',pitchprob
       !end if
       
       S_LA=netot(cc)*params%cpp%density*C_C/(2*C_PI)* &
            (pm11/gam11)*(pm(cc)/gam(cc))* &
            pitchprob*dsigdgam*secthreshgam

       !! Saving maximum secondary RE source for use in rejection-acceptance
       !! sampling algorithm 
       S_LAmax=maxval(S_LA)
       
       S_LA=S_LA*sin(eta11)

       !! Trapezoidal integration of secondary RE source to find probabilty
       
       do ii=1,ngam1
          probtmp(ii)=S_LA(ii,1)*deta1(1)/2+S_LA(ii,neta1)*deta1(neta1-1)/2
          !intpitchprob(ii)=pitchprob(ii,1)*sin(eta1(1))*deta1(1)/2+ &
          !     pitchprob(ii,neta1)*sin(eta1(neta1))*deta1(neta1-1)/2
          do jj=2,neta1-1
             probtmp(ii)=probtmp(ii)+S_LA(ii,jj)*(deta1(jj)+deta1(jj-1))/2
          !   intpitchprob(ii)=intpitchprob(ii)+ &
          !        pitchprob(ii,jj)*sin(eta1(jj))*(deta1(jj)+deta1(jj-1))/2
          end do
       end do

       prob1(cc)=probtmp(1)*dpm1(1)/2+probtmp(ngam1)*dpm1(ngam1-1)/2
       do jj=2,ngam1-1
          prob1(cc)=prob1(cc)+probtmp(jj)*(dpm1(jj)+dpm1(jj-1))/2
       end do

       !write(6,*) 'prob1pre',prob1(cc),'flagCol',flagCol(cc),'flagCon',flagCon(cc),'dt',dt
       
       !write(6,*) 'intpitchprob',intpitchprob
       
       prob1(cc)=prob1(cc)*dt*2*C_PI*REAL(flagCol(cc))*REAL(flagCon(cc))

       if (ISNAN(prob1(cc))) then
          write(6,*) 'NaN probability from secondary RE source'
          write(6,*) 'p,xi',pm(cc),xi(cc)
          write(6,*) 'gam_min,gammax',gam_min,gammax
          write(6,*) 'E',E_PHI(cc)*params%cpp%Eo
          write(6,*) 'E_C',E_C*params%cpp%Eo
          !write(6,*) 'pitchprob',pitchprob
          !write(6,*) 'S_LA',S_LA
          call korc_abort(24)
       end if

       if (prob1(cc).gt.1._rp) then
          write(6,*) 'Multiple secondary REs generated in a collisional time step'
          write(6,*) 'p,xi',pm(cc),xi(cc)
          write(6,*) 'gam_min,gammax',gam_min,gammax
          write(6,*) 'E',E_PHI(cc)*params%cpp%Eo
          write(6,*) 'E_C',E_C*params%cpp%Eo
          call korc_abort(24)
       end if

       !write(6,*) 'gam',gam(cc),'xi',xi(cc)
       !write(6,*) 'prob1',prob1(cc),'prob0',prob0(cc)
       
       if (prob1(cc).gt.prob0(cc)) then

          !! If secondary RE generated, begin acceptance-rejection sampling
          !! algorithm
          
          !write(6,*) 'secondary RE from ',prob1,prob0
          
          accepted=.false.

          gamsecmax=(gam(cc)+1)/2
          psecmax=sqrt(gamsecmax**2-1)

          seciter=0
          do while (.not.accepted)

             ptrial=p_min+(psecmax-p_min)*get_random()
             gamtrial=sqrt(1+ptrial*ptrial)

             cosgam1=sqrt(((gam(cc)+1)*(gamtrial-1))/((gam(cc)-1)*(gamtrial+1)))
             
             !xirad=sqrt((cosgam1*xi(cc))**2-(xi(cc)**2+cosgam1**2-1))

             !if (isnan(xirad)) then
             !   write(6,*) 'Sample not in allowable region of phase space'
             !   call korc_abort(24)
             !end if

             !xip=cosgam1*xi(cc)+xirad
             !xim=cosgam1*xi(cc)-xirad

             !xitrial=xim+(xip-xim)*get_random()
             xitrial=-1+2*get_random()

             sinsq1=(1-xi(cc)*xi(cc))*(1-xitrial*xitrial)
             cossq1=(cosgam1-xi(cc)*xitrial)**2
             pitchprob1=1/(C_PI*sqrt(sinsq1-cossq1))

             !if (isnan(pitchprob1)) cycle

             dsigdgam1=2*C_PI*C_RE**2/(gam(cc)**2-1)* &
                  (((gam(cc)-1)**2*gam(cc)**2)/ &
                  ((gamtrial-1)**2*(gam(cc)-gamtrial)**2)- &
                  (2*gam(cc)**2+2*gam(cc)-1)/ &
                  ((gamtrial-1)*(gam(cc)-gamtrial))+1)

             S_LA1=netot(cc)*params%cpp%density*C_C/(2*C_PI)* &
                  (ptrial/gamtrial)*(pm(cc)/gam(cc))* &
                  pitchprob1*dsigdgam1

             if (S_LA1/S_LAmax.gt.get_random()) accepted=.true.

             seciter=seciter+1

             !if (mod(seciter,100).eq.0) then
             !   write(6,*) 'iteration',seciter
             !end if
             
          end do

          !! Write secondary RE degrees of freedom to particle derived type

          
          !$OMP ATOMIC UPDATE
          spp%pRE=spp%pRE+1
          !$OMP ATOMIC WRITE
          spp%vars%flagRE(spp%pRE)=1
          !$OMP ATOMIC WRITE
          spp%vars%flagCon(spp%pRE)=1
          !$OMP ATOMIC WRITE
          spp%vars%flagCol(spp%pRE)=1
          !$OMP ATOMIC WRITE
          spp%vars%V(spp%pRE,1)=ptrial*xitrial
          !$OMP ATOMIC WRITE
          spp%vars%V(spp%pRE,2)=ptrial*ptrial*(1-xitrial*xitrial)/ &
               (2*me*Bmag(cc))
          !$OMP ATOMIC WRITE
          spp%vars%Y(spp%pRE,1)=Y_R(cc)
          !$OMP ATOMIC WRITE
          spp%vars%Y(spp%pRE,2)=Y_PHI(cc)
          !$OMP ATOMIC WRITE
          spp%vars%Y(spp%pRE,3)=Y_Z(cc)
          
          !! Write changes to primary RE degrees of freedom to temporary
          !! arrays for passing back out to particle derived type

#if DBG_CHECK    
          if (spp%vars%V(spp%pRE,2).lt.0._rp) then
             write(6,*) 'mu is negative for secondary'
             write(6,*) 'ppll,mu',spp%vars%V(spp%pRE,1),spp%vars%V(spp%pRE,2)
             write(6,*) 'pm,xi',ptrial,xitrial
             write(6,*) 'xim,xip',xim,xip
             write(6,*) 'pmin,psecmax',p_min,psecmax
             call korc_abort(24)
          end if
# endif
          
          if (cparams_ss%ConserveLA) then
             tmppm=pm(cc)
             gamvth=1/sqrt(1-2*Te(cc))
             gam(cc)=gam(cc)-gamtrial+gamvth
             pm(cc)=sqrt(gam(cc)*gam(cc)-1)
             xi(cc)=(tmppm*xi(cc)-ptrial*xitrial)/pm(cc)
          end if

          !$OMP ATOMIC READ
          pRE=spp%pRE
          
          if (pRE.eq.spp%ppp) then
             write(6,*) 'All REs allocated on proc',params%mpi_params%rank
             call korc_abort(24)
          end if
          
       end if
       
    end do


    
  end subroutine large_angle_source

  
  subroutine save_params_ms(params)
    TYPE(KORC_PARAMS), INTENT(IN) 			:: params
    CHARACTER(MAX_STRING_LENGTH) 			:: filename
    CHARACTER(MAX_STRING_LENGTH) 			:: gname
    CHARACTER(MAX_STRING_LENGTH), DIMENSION(:), ALLOCATABLE :: attr_array
    CHARACTER(MAX_STRING_LENGTH) 			:: dset
    CHARACTER(MAX_STRING_LENGTH) 			:: attr
    INTEGER(HID_T) 					:: h5file_id
    INTEGER(HID_T) 					:: group_id
    INTEGER 						:: h5error
    REAL(rp) 						:: units

    if (params%mpi_params%rank .EQ. 0) then
       filename = TRIM(params%path_to_outputs) // "simulation_parameters.h5"
       call h5fopen_f(TRIM(filename), H5F_ACC_RDWR_F, h5file_id, h5error)

       gname = "collisions_ms"
       call h5gcreate_f(h5file_id, TRIM(gname), group_id, h5error)

       ALLOCATE(attr_array(cparams_ms%num_impurity_species))

       dset = TRIM(gname) // "/model"
       call save_string_parameter(h5file_id,dset,(/params%collisions_model/))

       dset = TRIM(gname) // "/num_impurity_species"
       attr = "Number of impurity species"
       call save_to_hdf5(h5file_id,dset,cparams_ms%num_impurity_species,attr)

       dset = TRIM(gname) // "/Te"
       attr = "Background electron temperature in eV"
       units = params%cpp%temperature/C_E
       call save_to_hdf5(h5file_id,dset,units*cparams_ms%Te,attr)

       dset = TRIM(gname) // "/ne"
       attr = "Background electron density in m^-3"
       units = params%cpp%density
       call save_to_hdf5(h5file_id,dset,units*cparams_ms%ne,attr)

       dset = TRIM(gname) // "/nH"
       attr = "Background proton density in m^-3"
       units = params%cpp%density
       call save_to_hdf5(h5file_id,dset,units*cparams_ms%nH,attr)

       dset = TRIM(gname) // "/nef"
       attr = "Free electron density in m^-3"
       units = params%cpp%density
       call save_to_hdf5(h5file_id,dset,units*cparams_ms%nef,attr)

       dset = TRIM(gname) // "/neb"
       attr_array(1) = "Bound electron density per impurity in m^-3"
       units = params%cpp%density
       call save_1d_array_to_hdf5(h5file_id,dset,units*cparams_ms%neb, &
            attr_array)

       dset = TRIM(gname) // "/Zo"
       attr_array(1) = "Full nuclear charge of impurities"
       call save_1d_array_to_hdf5(h5file_id,dset,cparams_ms%Zo,attr_array)

       dset = TRIM(gname) // "/Zj"
       attr_array(1) = "Average charge state of impurities"
       call save_1d_array_to_hdf5(h5file_id,dset,cparams_ms%Zj,attr_array)

       dset = TRIM(gname) // "/nz"
       attr_array(1) = "Density of impurities in m^-3"
       units = params%cpp%density
       call save_1d_array_to_hdf5(h5file_id,dset,units*cparams_ms%nz,attr_array)

       dset = TRIM(gname) // "/IZj"
       attr_array(1) = " Ionization energy of impurities in eV"
       units = params%cpp%energy/C_E
       call save_1d_array_to_hdf5(h5file_id,dset,units*cparams_ms%IZj, &
            attr_array)

       dset = TRIM(gname) // "/rD"
       attr = "Debye length in m"
       units = params%cpp%length
       call save_to_hdf5(h5file_id,dset,units*cparams_ms%rD,attr)

       dset = TRIM(gname) // "/re"
       attr = "Classical electron radius in m"
       units = params%cpp%length
       call save_to_hdf5(h5file_id,dset,units*cparams_ms%re,attr)

       dset = TRIM(gname) // "/Ec"
       attr = "Critical electric field with impurities"
       units = params%cpp%Eo
       call save_to_hdf5(h5file_id,dset,units*cparams_ms%Ec_min,attr)
       
       DEALLOCATE(attr_array)

       call h5gclose_f(group_id, h5error)

       call h5fclose_f(h5file_id, h5error)
    end if
  end subroutine save_params_ms


  subroutine save_params_ss(params)
    TYPE(KORC_PARAMS), INTENT(IN) 				:: params
    CHARACTER(MAX_STRING_LENGTH) 				:: filename
    CHARACTER(MAX_STRING_LENGTH) 				:: gname
    CHARACTER(MAX_STRING_LENGTH) 				:: subgname
    CHARACTER(MAX_STRING_LENGTH), DIMENSION(:), ALLOCATABLE :: attr_array
    CHARACTER(MAX_STRING_LENGTH) 				:: dset
    CHARACTER(MAX_STRING_LENGTH) 				:: attr
    INTEGER(HID_T) 						:: h5file_id
    INTEGER(HID_T) 						:: group_id
    INTEGER(HID_T) 						:: subgroup_id
    INTEGER 							:: h5error
    REAL(rp) 							:: units


    if (params%mpi_params%rank .EQ. 0) then
       filename = TRIM(params%path_to_outputs) // "simulation_parameters.h5"
       call h5fopen_f(TRIM(filename), H5F_ACC_RDWR_F, h5file_id, h5error)

       gname = "collisions_ss"
       call h5gcreate_f(h5file_id, TRIM(gname), group_id, h5error)

       ALLOCATE(attr_array(cparams_ms%num_impurity_species))

       dset = TRIM(gname) // "/collisions_model"
       call save_string_parameter(h5file_id,dset,(/params%collisions_model/))

       dset = TRIM(gname) // "/Te"
       attr = "Background electron temperature in eV"
       units = params%cpp%temperature/C_E
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%Te,attr)

       dset = TRIM(gname) // "/Ti"
       attr = "Background ion temperature in eV"
       units = params%cpp%temperature/C_E
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%Ti,attr)

       dset = TRIM(gname) // "/ne"
       attr = "Background electron density in m^-3"
       units = params%cpp%density
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%ne,attr)

       dset = TRIM(gname) // "/Zeff"
       attr = "Effective nuclear charge of impurities"
       call save_to_hdf5(h5file_id,dset,cparams_ss%Zeff,attr)

       dset = TRIM(gname) // "/rD"
       attr = "Debye length in m"
       units = params%cpp%length
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%rD,attr)

       dset = TRIM(gname) // "/re"
       attr = "Classical electron radius in m"
       units = params%cpp%length
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%re,attr)

       dset = TRIM(gname) // "/Clogee"
       attr = "Coulomb logarithm"
       call save_to_hdf5(h5file_id,dset,cparams_ss%CoulombLogee,attr)

       dset = TRIM(gname) // "/Clogei"
       attr = "Coulomb logarithm"
       call save_to_hdf5(h5file_id,dset,cparams_ss%CoulombLogei,attr)
       
       dset = TRIM(gname) // "/VTe"
       attr = "Background electron temperature"
       units = params%cpp%velocity
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%VTe,attr)

       dset = TRIM(gname) // "/delta"
       attr = "Delta parameter VTe/C"
       call save_to_hdf5(h5file_id,dset,cparams_ss%delta,attr)

       dset = TRIM(gname) // "/Gamma"
       attr = "Gamma coefficient"
       units = (params%cpp%mass**2*params%cpp%velocity**3)/params%cpp%time
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%Gammac,attr)

       dset = TRIM(gname) // "/Tau_rad"
       attr = "Synchroton damping time in s"
       units = params%cpp%time
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%taur,attr)
       
       dset = TRIM(gname) // "/Tau"
       attr = "Relativistic collisional time in s"
       units = params%cpp%time
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%Tau,attr)

       dset = TRIM(gname) // "/Tauc"
       attr = "Thermal collisional time in s"
       units = params%cpp%time
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%Tauc,attr)

       dset = TRIM(gname) // "/dTau"
       attr = "Subcycling time step in s"
       units = params%cpp%time
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%dTau* &
            cparams_ss%Tau,attr)

       dset = TRIM(gname) // "/subcycling_iterations"
       attr = "KORC iterations per collision"
       call save_to_hdf5(h5file_id,dset,cparams_ss%subcycling_iterations,attr)

       dset = TRIM(gname) // "/Ec"
       attr = "Critical electric field"
       units = params%cpp%Eo
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%Ec,attr)

       dset = TRIM(gname) // "/ED"
       attr = "Dreicer electric field"
       units = params%cpp%Eo
       call save_to_hdf5(h5file_id,dset,units*cparams_ss%ED,attr)

       call h5gclose_f(group_id, h5error)

       call h5fclose_f(h5file_id, h5error)
    end if
  end subroutine save_params_ss


  subroutine save_collision_params(params)
    TYPE(KORC_PARAMS), INTENT(IN) :: params

    if (.NOT.(params%restart)) then

       if (params%collisions) then
          SELECT CASE (TRIM(params%collisions_model))
          CASE (MODEL1)
             call save_params_ss(params)

             SELECT CASE(TRIM(params%bound_electron_model))
             CASE ('NO_BOUND')
                call save_params_ms(params)
             CASE('HESSLOW')
                call save_params_ms(params)
             CASE('ROSENBLUTH')
                call save_params_ms(params)
             CASE DEFAULT
                write(output_unit_write,'("Default case")')
             END SELECT
             
          CASE (MODEL2)
             call save_params_ms(params)
          CASE DEFAULT
             write(output_unit_write,'("Default case")')
          END SELECT
       end if

    end if
  end subroutine save_collision_params


  subroutine deallocate_params_ms()
    if (ALLOCATED(cparams_ms%Zj)) DEALLOCATE(cparams_ms%Zj)
    if (ALLOCATED(cparams_ms%Zo)) DEALLOCATE(cparams_ms%Zo)
    if (ALLOCATED(cparams_ms%nz)) DEALLOCATE(cparams_ms%nz)
    if (ALLOCATED(cparams_ms%neb)) DEALLOCATE(cparams_ms%neb)
    if (ALLOCATED(cparams_ms%IZj)) DEALLOCATE(cparams_ms%IZj)
    if (ALLOCATED(cparams_ms%Zj)) DEALLOCATE(cparams_ms%Ee_IZj)
  end subroutine deallocate_params_ms


  subroutine deallocate_collisions_params(params)
    TYPE(KORC_PARAMS), INTENT(IN) :: params

    if (params%collisions) then
       SELECT CASE (TRIM(params%collisions_model))
       CASE (MODEL1)
          !				write(output_unit_write,'("Something to be done")')

          SELECT CASE(TRIM(params%bound_electron_model))
          CASE ('NO_BOUND')
             call deallocate_params_ms()
          CASE('HESSLOW')
             call deallocate_params_ms()
          CASE('ROSENBLUTH')
             call deallocate_params_ms()
          CASE DEFAULT
             write(output_unit_write,'("Default case")')
          END SELECT
          
       CASE (MODEL2)
          call deallocate_params_ms()
       CASE DEFAULT
          write(output_unit_write,'("Default case")')
       END SELECT
    end if
  end subroutine deallocate_collisions_params

end module korc_collisions