nuflux_class.f90
Go to the documentation of this file.
1 !> @file nuflux_class.f90
2 !!
3 !! The error file code for this file is ***W33***.
4 !!
5 !! @brief Module \ref nuflux_class and nu-flux related stuff
6 !!
7 
8 
9 !> Contains variables and parameters related to neutrino fluxes
10 !!
11 !! The neutrino temperature grid that is used for the reaction rates
12 !! can be changed here.
13 #include "macros.h"
18  use parser_module, only: parse_string
22  implicit none
23 
24 
25 !> Channel type for neutrino reactions according to
26 !! [Sieverding et al. 2018](https://ui.adsabs.harvard.edu/abs/2018ApJ...865..143S/abstract)
27  type,public :: nu_channel_type
28  integer :: id !< Channel ID
29  integer :: n_n !< number of neutrons emitted
30  integer :: n_p !< number of protons emitted
31  integer :: n_a !< number of alpha particles emitted
32  integer :: zdiff !< change in atomic number
33  integer :: adiff !< change in mass number
34  integer :: type !< 1: Charged current nue, 2: Charged current nuebar,
35  ! 3: Neutral current nux, 4: Neutral current nuxbar
36  end type nu_channel_type
37  type(nu_channel_type), dimension(:), allocatable :: nu_channels !< Array of neutrino channels
38 
39  integer :: nnu !< Amount of neutrino reactions
40 
41  type(reactionrate_type), dimension(:), allocatable :: rrate_nu !< Neutrino rate array
42 
43 
44 ! --- parameters
45  real(r_kind),dimension(4), public :: fluxnu !< @brief Neutrino fluxes
46  !< This variable is calculated and
47  !< set in \ref nuflux.
48  !< The dimension 4 accounts
49  !< for the different neutrino flavors,
50  !< however, only (anti-)electron neutrinos
51  !< are implemented at the moment.
52 
53  real(r_kind),dimension(4), private :: tempnu !< @brief Neutrino temperatures.
54  !< This variable is set in \ref nutemp
55  !< either from the values of a
56  !< trajectory or from an analytic
57  !< expression. The dimension 4 accounts
58  !< for the different neutrino flavors,
59  !< however, only (anti-)electron neutrinos
60  !< are implemented at the moment.
61 
62  integer, parameter :: nt_nugrid=7 !< Length of the neutrino rate grid
63 
64  real(r_kind),private :: sigtempnu(nt_nugrid) = &
65  (/2.8d0,3.5d0,4.0d0,5.0d0,6.4d0,8.0d0,10.0d0/) !< temperature grid for neutrino cross sections
66  !< @warning This neutrino temperature grid has to
67  !< match with the one in the files neunuclei.dat,
68  !< neunucleon.dat, and aneunuclei.dat
69 
70  real(r_kind), private :: rs !< Schwarzschild radius for M=mns [km], calculated in init_nuflux
71 
72  ! Helper variables for reading neutrino rates on heavier nuclei
73  type(nurate_type),dimension(:),allocatable,private :: anunuc !< anti-neutrino reactions on nuclides
74  type(nurate_type),dimension(:),allocatable,private :: nunuc !< neutrino reactions on nuclides
75 
76 
77 !--Debugging
78  integer,private :: lumin_debugfile !< Debug file to write neutrino luminosities,
79  !< neutrinospheres, and temperatures.
80 
81 
82 !...total luminosity
83 ! cross sections are of order 10^-42 [cm^2]
84 ! luminosity is of order 10^51 [erg]
85 ! ==> overall factor of 10^9
86 ! data lumtot /17.9d9,17.7d9,0.0d0,0.0d0/
87 
88 ! --- variables
89  real(r_kind),dimension(:),allocatable,public :: tnue,tnuebar !< (anti-)electron neutrino temperatures from trajectory
90  real(r_kind),dimension(:),allocatable,public :: tnux,tnuxbar !< (anti-)mu and tau neutrino temperatures from trajectory
91  real(r_kind),dimension(:),allocatable,public :: nlume,nlumebar !< (anti-)electron neutrino number luminosities from trajectory
92  real(r_kind),dimension(:),allocatable,public :: nlumx,nlumxbar !< (anti-)mu and tau neutrino number luminosities from trajectory
93 
94  logical,private :: include_nc_reactions !< Flag to include neutrino reactions that are not charged current
95  integer,private :: n_nuclei,n_anuclei,n_nucleo, n_cc, n_nc
96 
97 
98  character(len=*), parameter, private:: nu_binary_name = "nu_binary.windat" !< Name of the neutrino binary file
99 
100  !
101  ! Public and private fields and methods of the module.
102  !
103  public:: &
106  private:: &
110 
111 contains
112 
113 
114 !>
115 !! Initialize nuflux module
116 !!
117 !! Calculates the Schwarzschild radius
118 !! and opens debug files and writes headers to them.
119 !! Furthermore it reads the neutrino reactions
120 !!
121 !! \b Edited:
122 !! - 12.04.17
123 !! - 25.01.21, MR - Moved the reading of the nu-rates to this place
124 !! .
125 subroutine init_nuflux()
128  implicit none
129 
130  ! Count individual reaction rates
131  n_nuclei=0; n_anuclei=0; n_nucleo=0; n_cc=0; n_nc=0;
132 
133  if (nuflag .ge. 1) then
134 
135  if ((nuflag .eq. 3) .or. (nuflag .eq. 4)) then
136  include_nc_reactions = .true.
137  else
138  include_nc_reactions = .false.
139  end if
140 
141  ! Open debug file
142  if (verbose_level .gt. 2.) then
143  lumin_debugfile = open_outfile('debug_lumin.dat')
144  write(lumin_debugfile,*) 'Debug file of nuflux_class.f90'
145  ! TODO Add better description
146  write(lumin_debugfile,'(A)') ' Time [s], NLume [1/s], NLumebar [1/s], Fnue, Fnuebar, R[cm]'
147  endif
148 
149  if (use_prepared_network) then
151  else
152  !-- Read neutrino reactions
153  call read_neutrino_rates()
154  end if
155 
156  !-- Give output statistics
158  end if
159 
160 end subroutine init_nuflux
161 
162 
163 !>
164 !! Determines neutrino flux for current time (in units of cm^-2 s^-1).
165 !!
166 !! The flux is hereby either based on an analytic forumlas of the
167 !! neutrino luminosities and energies or on the trajectory file.
168 !!
169 !! @note In previous versions, also GR corrections were applied here, c.f.,
170 !! [Otsuki et al. 2000](https://ui.adsabs.harvard.edu/abs/2000ApJ...533..424O/abstract).
171 !!
172 !! \b Edited:
173 !! - 11.01.14
174 !! - MR 18.12.20
175 !! .
176 subroutine nuflux(time, rkm)
177  use parameter_class, only: unit
178  use inter_module
179  implicit none
180 
181  real(r_kind), intent(in) :: time !< current time
182  real(r_kind) :: rkm !< radius in km
183  !
184  integer :: i
185  integer :: itime !index for interpolation
186  integer :: inuf !neutrino flavor
187  real(r_kind),dimension(4) :: c0nu !constant for all 4 nu-flavors
188  real(r_kind) :: frac !
189  real(r_kind) :: rcm !radius in cm
190  real(r_kind) :: r2 !4*pi*r*r
191  real(r_kind), dimension(4) :: nlum !current neutrino luminosities
192  real(r_kind), dimension(4) :: fluxcom !current neutrino fluxes for all 4 flavours
193 
194  ! Interpolate (or convert from energies to) neutrino temperatures
195  call nutemp(time)
196 
197  ! account for cross section units of 10^-42 cm^2
198  c0nu = 1.0d-42
199 
200  !...radius in units of cm; include factor 4*pi
201  rcm = rkm*1.d5
202  r2=4.d0*unit%pi*rcm*rcm
203 
204 
205  select case (neutrino_mode)
206 
207  ! for use with analytic neutrino quantities
208  case ("analytic")
209 !...initialize variables
210 
211  nlum(1) = parse_string(le,time) ![erg/s]
212  nlum(2) = parse_string(lebar,time) ![erg/s]
213 
214  ! Also include heavier neutrinos
215  if (include_nc_reactions) then
216  nlum(3) = parse_string(lx,time) ![erg/s]
217  nlum(4) = parse_string(lxbar,time) ![erg/s]
218  end if
219 
220  ! Use data from luminosity file
221  case ('from_file')
222 
223  ! Interpolate the neutrino luminosities
224  itime = 0
225  if ( time > ztime(1) .and. time <= ztime(zsteps) ) then
226 
227  do i=1,zsteps
228  if ( time <= ztime(i) ) exit
229  end do
230  itime=i
231  frac=(time-ztime(itime-1))/(ztime(itime)-ztime(itime-1))
232  nlum(1)=nlume(itime-1)+frac*(nlume(itime)-nlume(itime-1))
233  nlum(2)=nlumebar(itime-1)+frac*(nlumebar(itime)-nlumebar(itime-1))
234  ! Also include other neutrino flavors
235  if (include_nc_reactions) then
236  nlum(3)=nlumx(itime-1)+frac*(nlumx(itime)-nlumx(itime-1))
237  nlum(4)=nlumxbar(itime-1)+frac*(nlumxbar(itime)-nlumxbar(itime-1))
238  end if
239 
240  else if ( time > ztime(zsteps) ) then
241  nlum(1) = nlume(zsteps)
242  nlum(2) = nlumebar(zsteps)
243  ! Also include other neutrino flavors
244  if (include_nc_reactions) then
245  nlum(3) = nlumx(zsteps)
246  nlum(4) = nlumxbar(zsteps)
247  end if
248  else if ( time .eq. ztime(1) ) then
249  nlum(1) = nlume(1)
250  nlum(2) = nlumebar(1)
251  ! Also include other neutrino flavors
252  if (include_nc_reactions) then
253  nlum(3) = nlumx(1)
254  nlum(4) = nlumxbar(1)
255  end if
256  end if
257  nlum(1)=dexp(nlum(1))
258  nlum(2)=dexp(nlum(2))
259  ! Also include other neutrino flavors
260  if (include_nc_reactions) then
261  nlum(3)=dexp(nlum(3))
262  nlum(4)=dexp(nlum(4))
263  end if
264 
265  if (nlum(1).lt.1e-20) nlum(1)=0.d0
266  if (nlum(2).lt.1e-20) nlum(2)=0.d0
267  if (include_nc_reactions) then
268  if (nlum(3).lt.1e-20) nlum(3)=0.d0
269  if (nlum(4).lt.1e-20) nlum(4)=0.d0
270  end if
271 
272 
273  end select
274 
275  ! Calculate number luminosities
276  ! Avoid neutrino reactions with very small energies
277  do inuf=1,2
278  if (tempnu(inuf) .le. 1e-20) then
279  nlum(inuf) = 0.d0
280  else
281  nlum(inuf) = nlum(inuf)*unit%ergtomev/(tempnu(inuf)*3.151374374)
282  end if
283  end do
284 
285  if (include_nc_reactions) then
286  do inuf=3,4
287  if (tempnu(inuf) .le. 1e-20) then
288  nlum(inuf) = 0.d0
289  else
290  nlum(inuf) = nlum(inuf)*unit%ergtomev/(tempnu(inuf)*3.151374374)
291  end if
292  end do
293  end if
294 
295 
296  fluxcom=0.d0
297  fluxnu=0.d0
298  do inuf=1,2
299  fluxcom(inuf) = c0nu(inuf) * nlum(inuf) / r2
300  fluxnu(inuf) = fluxcom(inuf)
301  end do
302 
303  if (include_nc_reactions) then
304  do inuf=3,4
305  fluxcom(inuf) = c0nu(inuf) * nlum(inuf) / r2
306  fluxnu(inuf) = fluxcom(inuf)
307  end do
308  end if
309 
310  ! Verbose output
311  if (verbose_level .gt. 2) then
312  write(lumin_debugfile,'(6(es23.14,5x))') &
313  time, nlum(1), nlum(2),fluxnu(1)/c0nu(1),fluxnu(2)/c0nu(2),rcm
314  endif
315 
316  return
317 end subroutine nuflux
318 
319 
320 
321 !> Calculates the cross section times the neutrino flux.
322 !!
323 !! This subroutine calculates the cross section times
324 !! the neutrino flux for a given neutrino reaction. Here,
325 !! the different neutrino types are distinguised.
326 !! 1: CC reaction (electron neutrino)
327 !! 2: CC reaction (anti-electron neutrino)
328 !! 3: NC reaction (all neutrinos)
329 !! 4: NC reaction (all anti-neutrinos)
330 !! .
331 !!
332 !! \b Edited:
333 !! - 12.02.23 MR: Moved this from the jacobian class here
334 !! .
335 subroutine calculate_nu_rate(rrate,rat_calc)
336  use global_class, only: nurate
337  implicit none
338  ! Declare the pass
339  type(reactionrate_type),intent(inout) :: rrate !< rate instance
340  real(r_kind),intent(out) :: rat_calc !< rate value
341  ! Internal variables
342  integer :: wind !< Weak index
343  type(nurate_type) :: nurate_tmp!< temporary nurate instance
344  real(r_kind) :: av_e !< Average energy
345 
346  ! Save the source flag
347  wind = int(rrate%param(1))
348  nurate_tmp = nurate(wind)
349 
350  rrate%nu_frac = 0
351 
352  ! Get the rate
353  if (nurate_tmp%kind .eq. 1) then
354  rat_calc = fluxnu(1)*nurate(wind)%rcs_e
355  rrate%nu_frac = -1d0*sign(1d0,rrate%q_value)*abs(nurate(wind)%ravE/rrate%q_value)
356  else if (nurate_tmp%kind .eq. 2) then
357  rat_calc = fluxnu(2)*nurate(wind)%rcs_e
358  rrate%nu_frac = -1d0*sign(1d0,rrate%q_value)*abs(nurate(wind)%ravE/rrate%q_value)
359  else if (nurate_tmp%kind .eq. 3) then
360  rat_calc = fluxnu(1)*nurate(wind)%rcs_e + &
361  fluxnu(3)*nurate(wind)%rcs_x
362  rrate%nu_frac = -1d0*sign(1d0,rrate%q_value)*abs(nurate(wind)%ravE/rrate%q_value)
363  else if (nurate_tmp%kind .eq. 4) then
364  rat_calc = fluxnu(2)*nurate(wind)%rcs_e + &
365  fluxnu(4)*nurate(wind)%rcs_x
366  rrate%nu_frac = -1d0*sign(1d0,rrate%q_value)*abs(nurate(wind)%ravE/rrate%q_value)
367  else
368  call raise_exception("Neutrino kind not implemented yet. "// &
369  "Got: "//trim(int_to_str(nurate_tmp%kind))//". "// &
370  "Only 1, 2 (CC) and 3, 4 (NC) are supported.", &
371  "calculate_nu_rate", 330003)
372  end if
373 
374 
375  return
376 end subroutine calculate_nu_rate
377 
378 
379 
380 !>
381 !! Interpolate neutrino cross sections
382 !!
383 !! The subroutine lin-log interpolates the neutrino cross sections
384 !! depending on the neutrino temperature (stored in \ref tempnu).
385 !! For this it also uses the temperature grid \ref sigtempnu.
386 !! The final interpolated cross sections are stored in
387 !! \ref global_class::nurate\%rcs.
388 !!
389 !! @returns reaction cross sections for neutrino reactions into
390 !! \ref global_class::nurate\%rcs.
391 !!
392 !! \b Edited:
393 !! - 13.01.14
394 !! - 27.01.21
395 !! - 19.07.22, M.R., removed small bug when at the interpolation boundary
396 !! - 22.02.23, M.R., removed possible division by zero
397 !! .
398 subroutine nucs()
399  use global_class, only: nurate
400  implicit none
401 
402  integer :: i,j,n,k, typ
403  integer, dimension(4) :: isave
404  real(r_kind) :: rcs !cross section for neutrino reaction
405  real(r_kind), dimension(4) :: frac
406  real(r_kind) :: cs1,cs2,t1,t2,ave,ave1,ave2
407  real(r_kind), dimension(2) :: csg
408  integer :: start
409  integer :: count
410 
411  n = size(nurate)
412 !...interpolate neutrino cross sections
413  do j=1,4
414  do i=1,nt_nugrid
415  if ( tempnu(j) .le. sigtempnu(i) ) exit
416  end do
417 !.....isave gives the upper value for interpolation.....................
418  isave(j)=i
419  if ((isave(j).le.1).or.(isave(j).gt.nt_nugrid)) cycle
420  t2=dlog(sigtempnu(isave(j)))
421  t1=dlog(sigtempnu(isave(j)-1))
422  frac(j)=(dlog(tempnu(j))-t1)/(t2-t1)
423  end do
424 
425 
426  do i=1,n
427  typ = nurate(i)%kind
428  start = typ
429  ! We also want to calculate the cs for electron (anti-)neutrinos
430  if (typ .gt. 2) start = typ-2
431  count = 0
432  ! Calculate reactions for electron neutrinos, and muon/tauon neutrinos
433  inner_loop: do k=start,4,2
434  count = count+1
435  if ( tempnu(k) .eq. 0.d0) then
436  csg(count) = 0.d0
437  ave = 0.d0
438  else if (maxval(tempnu(:)) .lt. sigtempnu(1)) then
439  ! If all temperatures are below the grid, set the cross section to zero
440  ! Otherwise calculate the cross section at the lowest grid point
441  csg(count) = 0
442  ave = 0
443  else if ( isave(k) .eq. 1 ) then
444  csg(count) = nurate(i)%cs(1)
445  ave = nurate(i)%avE(1)
446  else if ( isave(k) .gt. nt_nugrid ) then
447  csg(count) = nurate(i)%cs(nt_nugrid)
448  ave = nurate(i)%avE(nt_nugrid)
449  else
450  if (nurate(i)%cs(isave(k)) .eq. 0.0d0 ) then
451  cs2=dlog(tiny(rcs)) ! 2009-12-13
452  else
453  cs2=dlog(nurate(i)%cs(isave(k)))
454  end if
455 
456  if (nurate(i)%cs(isave(k)-1) .eq. 0.0d0 ) then ! 2009-12-13
457  cs1=dlog(tiny(rcs)) ! 2009-12-13
458  else ! 2009-12-13
459  cs1=dlog(nurate(i)%cs(isave(k)-1))
460  end if ! 2009-12-13
461  rcs=cs1+frac(k)*(cs2-cs1)
462  csg(count)=dexp(rcs)
463 
464  ! Calculate average energy of absorbed neutrinos
465  if ((nurate(i)%avE(isave(k)-1) .eq. 0.0d0 ) .or. &
466  (nurate(i)%avE(isave(k)) .eq. 0.0d0 )) then
467  ave = 0.0d0
468  else
469  ave1 = nurate(i)%avE(isave(k)-1)
470  ave2 = nurate(i)%avE(isave(k))
471  ave = ave1+frac(k)*(ave2-ave1)
472  end if
473  end if
474 
475  if (typ .le. 2) exit inner_loop
476  end do inner_loop
477  nurate(i)%rcs_e = csg(1)
478  nurate(i)%rcs_x = csg(2)
479  nurate(i)%ravE = ave
480  end do
481 
482  return
483 
484 end subroutine nucs
485 
486 
487 !>
488 !! @brief Calculates (anti-) neutrino temperatures.
489 !!
490 !! The determination depends on the \ref parameter_class::neutrino_mode.
491 !! In case of an analytic expression for the neutrino temperatures (or energies)
492 !! it evaluates and parses a string. In case of a trajectory determining the
493 !! temperatures, this subroutine lin-log interpolates (inside, e.g.,
494 !! \ref ztime and \ref tnue). The subroutine also
495 !! ensures that the temperature does not become negative.
496 !!
497 !! \b Edited:
498 !! - 13.01.14
499 !! - MR: 18.12.20
500 !! .
501 subroutine nutemp(time)
502  implicit none
503  integer, parameter :: iflux=0
504 
505  real(r_kind), intent(in) :: time !< current time
506  !
507  integer :: i
508  integer :: itime !index of current time
509  real(r_kind) :: frac
510 
511  ! Initialize neutrino temperatures
512  tempnu(:) = 0d0
513 
514  ! The determination of neutrino temperatures depends on the
515  ! neutrino mode
516  select case (neutrino_mode)
517  case ('analytic')
518 
519  tempnu(1) = parse_string(enue,time)/3.151374374
520  tempnu(2) = parse_string(enuebar,time)/3.151374374
521 
522  ! In case neutral current reactions are included
523  if (include_nc_reactions) then
524  tempnu(3) = parse_string(enux,time)/3.151374374
525  tempnu(4) = parse_string(enuxbar,time)/3.151374374
526  end if
527 
528  !...neutrino temperature (interpolate only if t < t_end(AB)
529  case ('from_file')
530 
531  tempnu(1)=tnue(1)
532  tempnu(2)=tnuebar(1)
533 
534  ! Check if heavier neutrinos are included
535  if (include_nc_reactions) then
536  tempnu(3)=tnux(1)
537  tempnu(4)=tnuxbar(1)
538  end if
539 
540  !...log interpolation
541  itime = 0
542  if ( time > ztime(1) .and. time < ztime(zsteps) ) then
543  do i=1,zsteps
544  if ( time <= ztime(i) ) exit
545  end do
546  itime=i
547  frac=(time-ztime(itime-1))/(ztime(itime)-ztime(itime-1))
548  tempnu(1)=tnue(itime-1)+frac*(tnue(itime)-tnue(itime-1))
549  tempnu(2)=tnuebar(itime-1)+frac*(tnuebar(itime)-tnuebar(itime-1))
550  if (include_nc_reactions) then
551  tempnu(3)=tnux(itime-1)+frac*(tnux(itime)-tnux(itime-1))
552  tempnu(4)=tnuxbar(itime-1)+frac*(tnuxbar(itime)-tnuxbar(itime-1))
553  end if
554  else if ( time >= ztime(zsteps) ) then
555  tempnu(1)=tnue(zsteps)
556  tempnu(2)=tnuebar(zsteps)
557  if (include_nc_reactions) then
558  tempnu(3)=tnux(zsteps)
559  tempnu(4)=tnuxbar(zsteps)
560  end if
561  end if
562  tempnu(1)=dexp(tempnu(1))
563  tempnu(2)=dexp(tempnu(2))
564  if (include_nc_reactions) then
565  tempnu(3)=dexp(tempnu(3))
566  tempnu(4)=dexp(tempnu(4))
567  end if
568 
569  end select
570 
571  ! Ensure positive temperatures
572  if (tempnu(1).lt.1e-20) tempnu(1)=0.d0
573  if (tempnu(2).lt.1e-20) tempnu(2)=0.d0
574 
575  if (include_nc_reactions) then
576  if (tempnu(3).lt.1e-20) tempnu(3)=0.d0
577  if (tempnu(4).lt.1e-20) tempnu(4)=0.d0
578  end if
579 
580  return
581 end subroutine nutemp
582 
583 
584 !> Write the amount of individual reactions to the out
585 !!
586 !! The rates are always counted, for a certain verbose level they
587 !! are also printed to the OUT file
588 !!
589 !! @author M. Reichert
590 !! @date 27.01.21
593  implicit none
594  character(len=7) :: tmp !< temporary character for pretty output
595 
596  if (verbose_level .ge. 1) then
597  call write_data_to_std_out("Amount neutrino rates",int_to_str(nnu))
598  elseif (verbose_level .ge. 2) then
599  if (nnu .gt. 0) write(*,"(A)") ""
600  if (nnu .gt. 0) write(*,"(A)") " Neutrino rates: "
601  if (nnu .gt. 0) write(*,"(A)") " |------------------------|"
602  tmp = int_to_str(nnu)
603  if (nnu .gt. 0) write(*,"(A)") " | Total :"//adjustr(tmp)//" |"
604  tmp = int_to_str(n_nucleo)
605  if (n_nucleo .gt. 0) write(*,"(A)") " | on nucleons :"//adjustr(tmp)//" |"
606  tmp = int_to_str(n_nuclei)
607  if (n_nuclei .gt. 0) write(*,"(A)") " | nue on nuclei :"//adjustr(tmp)//" |"
608  tmp = int_to_str(n_anuclei)
609  if (n_anuclei .gt. 0) write(*,"(A)") " | anue on nuclei:"//adjustr(tmp)//" |"
610  tmp = int_to_str(n_cc)
611  if (n_cc .gt. 0) write(*,"(A)") " | CC on nuclei :"//adjustr(tmp)//" |"
612  tmp = int_to_str(n_nc)
613  if (n_nc .gt. 0) write(*,"(A)") " | NC on nuclei :"//adjustr(tmp)//" |"
614  if (nnu .gt. 0) write(*,"(A)") " |------------------------|"
615  if (nnu .gt. 0) write(*,"(A)") ""
616  end if
617 
618 end subroutine write_reac_verbose_out
619 
620 
621 
622 !> Read neutrino reactions and fill the global_class::nurate array
623 !!
624 !! Depending on the nuflag parameter, different files will be opened and
625 !! read.
626 !!
627 !! @see readnucs
628 !!
629 !! \b Edited:
630 !! - 23.01.21, MR - Moved it to this subroutine from network_init_module
631 !! .
637  use benam_class, only: getcoefficients
639  implicit none
640  ! Internal variables
641  integer :: nunucleo !< Id for neutrino reaction file
642  integer :: i,j !< Loop variable
643 
644 
645  ! Count the amount of neutrino reactions
646  nnu = 0
647  !----- if neutrino rates are used read them from the respective files
648  select case(nuflag)
649  ! No neutrinos, just do nothing
650  case(0)
651  nnu = 0
652  continue
653  ! nuflag = 1...neutrinos only on neutrons and protons
654  case(1)
656  call readnucs(nunucleo,1)
657  close(nunucleo)
658  nnu = size(nurate)
659  ! Count individual reaction rates
660  n_nucleo = nnu
661  ! nuflag = 2, 3, 4 neutrino reactions on heavy nuclei from Sieverding et al. (2018)
662  ! 3: Only charged current reactions
663  ! 4: Only neutral current reactions
664  ! 5: Both charged and neutral current reactions
665  case(2:4)
667  call readnucs(nunucleo,1)
668  close(nunucleo)
669  ! Count individual reaction rates
670  n_nucleo = size(nurate)
671 
674  n_nuclei = size(nunuc)
675  call nurate_ms(nurate,size(nurate),nunuc,size(nunuc),0)
676  nnu = size(nurate)
677  case default
678  call raise_exception("Not implemented neutrino mode (nuflag: "// &
679  int_to_str(nuflag)//").", "read_neutrino_rates",&
680  330005)
681  end select
682 
683  ! set the neutrino type
684  call set_nutype(nnu)
685 
686  !----- create rrate-type array of neutrino rates, needed to merge them later
687  allocate(rrate_nu(nnu))
688  do i=1,nnu
689  rrate_nu(i)%group = 1 ! Put all in chapter 1 even when this may be a lie
690  rrate_nu(i)%parts = 0
691  rrate_nu(i)%parts(1:6) = nurate(i)%parts(1:6)
692  rrate_nu(i)%source = nurate(i)%source
693  rrate_nu(i)%ch_amount(:) = nurate(i)%ch_amount(:)
694  rrate_nu(i)%is_reverse = .false.
695  rrate_nu(i)%is_resonant = .false.
696  rrate_nu(i)%cached = -1
697  rrate_nu(i)%reac_type = rrt_nu
698  rrate_nu(i)%reac_src = rrs_nu
699  rrate_nu(i)%param(1) = dble(i)
700  rrate_nu(i)%is_weak = (nurate(i)%kind .eq. 1) .or. &
701  (nurate(i)%kind .eq. 2)
702  rrate_nu(i)%one_over_n_fac= 1
703  ! Calculate the Q-value
704  rrate_nu(i)%q_value = 0
705  do j=1,6
706  if (rrate_nu(i)%parts(j) .eq. 0) exit
707 
708  rrate_nu(i)%q_value = rrate_nu(i)%q_value - &
709  isotope(rrate_nu(i)%parts(j))%mass_exc*&
710  rrate_nu(i)%ch_amount(j)
711  end do
712 
713  end do
714 
715  ! sort them (just to be sure)
716  call rrate_sort(nnu,rrate_nu)
717 
718 
719  ! Dont call getcoefficients. The ch_amount is already
720  ! calculated in the nuflux_class and one_over_n_fac
721  ! is always 1 for neutrino reactions
722  ! call getcoefficients(rrate_nu,nnu)
723 
724 end subroutine read_neutrino_rates
725 
726 
727 !> Read the reactions from a file in binary format
728 !!
729 !! This subroutine reads neutrino reactions and all
730 !! neutrino data from a binary file. This file has
731 !! to be previously prepared.
732 !!
733 !! @author M. Reichert
734 !! @date 21.06.2023
737  use global_class, only: nurate
739  implicit none
740  ! Internal variables
741  character(len=*), intent(in) :: path !< Path to the output directory
742  integer :: file_id !< File ID
743  integer :: alloc_stat !< Allocation status
744 
745  if (nuflag .gt. 0) then
746  ! Open an unformatted file
747  file_id = open_unformatted_infile(trim(adjustl(path))//trim(adjustl(nu_binary_name)))
748 
749  read(file_id) nnu
750  read(file_id) n_nuclei, n_anuclei, n_nucleo, n_cc, n_nc
751  ! Allocate the arrays
752  allocate(nurate(nnu),stat=alloc_stat)
753  if (alloc_stat .ne. 0) then
754  call raise_exception("Could not allocate nurate array.", &
755  "read_binary_neutrino_reaction_data", 330001)
756  end if
757  read(file_id) nurate
758 
759  close(file_id)
760  end if
761 
763 
764 
765 !> Write the reactions to a file in binary format
766 !!
767 !! This subroutine writes the reactions to a file in binary format.
768 !! This is done for preparing a folder with all reaction rates that
769 !! can be read in later on from many tracers.
770 !!
771 !! @author M. Reichert
772 !! @date 21.06.2023
774  use parameter_class, only: nuflag
775  use global_class, only: nurate
777  implicit none
778  ! Internal variables
779  character(len=*), intent(in) :: path !< Path to the output directory
780  integer :: file_id !< File ID
781 
782  if (nuflag .gt. 0) then
783  ! Open an unformatted file
784  file_id = open_unformatted_outfile(trim(adjustl(path))//trim(adjustl(nu_binary_name)))
785 
786  write(file_id) nnu
787  write(file_id) n_nuclei, n_anuclei, n_nucleo, n_cc, n_nc
788  write(file_id) nurate
789 
790  close(file_id)
791  end if
792 
794 
795 
796 !> Read the reactions from a file in the format of Sieverding et al 2018
797 !!
798 !! This subroutine reads the reactions from a file in the format
799 !! of [Sieverding et al 2018](https://ui.adsabs.harvard.edu/abs/2018ApJ...865..143S/abstract).
800 !! The file contains the reaction rates for charged and neutral
801 !! current neutrino reactions on heavy nuclei.
802 !! An example of the file looks like:
803 !! \file{
804 !! 000 Z = 2 A = 4 channels: 6
805 !! 002 1.099778E-03 7.960983E-03 2.308440E-02 1.163089E-01 5.736357E-01 2.100826E+00 6.820661E+00
806 !! 023 1.145175E-03 7.713879E-03 2.115540E-02 9.541441E-02 4.077819E-01 1.295820E+00 3.633845E+00
807 !! ...
808 !! }
809 !! Here the first line contains the atomic number, the mass number and the amount of reactions.
810 !! The second line contains the channel specified in the channel file (see \ref read_channels)
811 !! followed by the reaction rates. The reaction rates are tabulated on a (neutrino) temperature grid
812 !! of Tnu (MeV) = 2.800 3.500 4.000 5.000 6.400 8.000 10.000.
813 !!
814 !! @author M. Reichert
815 !! @date 12.02.2023
816 subroutine read_reactions_sieverding(reaction_file_path, reactype)
818  use benam_class, only : findaz
820  implicit none
821  character(len=*), intent(in) :: reaction_file_path !< Path to the neutrino reaction file
822  integer, intent(in) :: reactype !< 0: charged current only,
823  ! 1: neutral current only,
824  ! 2: both
825  ! Internal variables
826  integer :: file_id !< File ID
827  integer :: nreactions !< Number of reactions
828  integer :: reac_count !< Reaction counter
829  integer :: i, j, k !< Loop variable
830  integer :: stat !< Status variable
831  integer :: istat !< Status variable
832  integer :: nchannels !< Number of channels
833  integer :: z !< Atomic number
834  integer :: a !< Mass number
835  integer :: z_out !< Proton number of the product
836  integer :: a_out !< Mass number of the product
837  integer :: ch_id !< Channel ID
838  real(r_kind),dimension(7) :: cs !< Cross section
839  integer :: nucl_id !< Network index of reacting nucleus
840  integer :: nucl_id_out !< Network index of product nucleus
841  integer :: ind !< Helper variable
842 
843  ! Open the file
844  file_id = open_infile(reaction_file_path)
845  ! Initialize the amount of reactions
846  nreactions = 0
847  ! Count the reactions
848  do
849  read(file_id,'(9x,i3,6x,i3,12x,i3)',iostat=stat) &
850  z, a, nchannels
851  if (stat.ne.0) exit
852  ! Check if nucleus is included in the network
853  nucl_id = findaz(a,z)
854 
855  if (nucl_id .ne. -1) then
856  ! Loop through the reactions
857  do j = 1, nchannels
858  read(file_id,'(I3, 2x, 7(E12.6,2x))') ch_id, cs(:)
859  ! Skip neutral current reactions
860 
861  if (((reactype .eq. 0 ) .and. (nu_channels(ch_id)%type .gt. 2))) cycle
862  ! Skip charged current reactions
863  if (((reactype .eq. 1 ) .and. (nu_channels(ch_id)%type .le. 2))) cycle
864 
865  ! Check if the reaction is included
866  z_out = z-nu_channels(ch_id)%Zdiff
867  a_out = a-nu_channels(ch_id)%Adiff
868  nucl_id_out = findaz(a_out,z_out)
869  if (nucl_id_out .ne. -1) nreactions = nreactions + 1
870  end do
871  else
872  ! Skip the reactions
873  do j = 1, nchannels
874  read(file_id,'(I3, 2x, 7(E12.6,2x))')
875  end do
876  end if
877  end do
878 
879  ! Allocate the nurate array
880  allocate(nunuc(nreactions),stat=istat)
881  if (istat.ne.0) call raise_exception('Allocation of "nunuc" failed.',&
882  "read_reactions_sieverding",330001)
883 
884  ! Rewind the file
885  rewind(file_id)
886 
887  ! Read the reactions
888  reac_count = 1
889  do
890  read(file_id,'(9x,i3,6x,i3,12x,i3)',iostat=stat) &
891  z, a, nchannels
892  if (stat.ne.0) exit
893  ! Check if nucleus is included in the network
894  nucl_id = findaz(a,z)
895 
896  if (nucl_id .ne. -1) then
897  ! Loop through the reactions
898  do j = 1, nchannels
899  read(file_id,'(I3, 2x, 7(E12.6,2x))') ch_id, cs(:)
900 
901  ! Skip neutral current reactions
902  if (((reactype .eq. 0 ) .and. (nu_channels(ch_id)%type .gt. 2))) cycle
903  ! Skip charged current reactions
904  if (((reactype .eq. 1 ) .and. (nu_channels(ch_id)%type .le. 2))) cycle
905 
906  ! Check if the reaction is included
907  z_out = z-nu_channels(ch_id)%Zdiff
908  a_out = a-nu_channels(ch_id)%Adiff
909  nucl_id_out = findaz(a_out,z_out)
910 
911  if (nucl_id_out .ne. -1) then
912  ! Store the reaction
913  nunuc(reac_count)%parts(:) = 0
914  nunuc(reac_count)%ch_amount(:) = 0
915  nunuc(reac_count)%parts(1) = nucl_id
916  nunuc(reac_count)%parts(2) = nucl_id_out
917  nunuc(reac_count)%ch_amount(1) = -1
918  nunuc(reac_count)%ch_amount(2) = 1
919 
920  ! Put protons, neutrons, and alphas in the reaction
921  ! parts array. Use the channel amount to specify
922  ! the number as it can be more particles than allowed
923  ! in the reaclib format
924  ind = 3
925  if (nu_channels(ch_id)%n_p .gt. 0) then
926  nunuc(reac_count)%parts(ind) = ipro
927  nunuc(reac_count)%ch_amount(ind) = nu_channels(ch_id)%n_p
928  ind = ind + 1
929  endif
930 
931  if (nu_channels(ch_id)%n_n .gt. 0) then
932  nunuc(reac_count)%parts(ind) = ineu
933  nunuc(reac_count)%ch_amount(ind) = nu_channels(ch_id)%n_n
934  ind = ind + 1
935  endif
936 
937  if (nu_channels(ch_id)%n_a .gt. 0) then
938  nunuc(reac_count)%parts(ind) = ihe4
939  nunuc(reac_count)%ch_amount(ind) = nu_channels(ch_id)%n_a
940  ind = ind + 1
941  endif
942 
943  ! Set the cross section, source, and type of the reaction
944  nunuc(reac_count)%source = "siev"
945  nunuc(reac_count)%cs(:) = cs(:)
946  nunuc(reac_count)%avE(:) = 0
947  nunuc(reac_count)%kind = nu_channels(ch_id)%type
948 
949  ! Count reactions for the output
950  if (nunuc(reac_count)%kind .le. 2) then
951  n_cc = n_cc + 1
952  else
953  n_nc = n_nc + 1
954  end if
955 
956  ! Count the reaction to know the index
957  reac_count = reac_count + 1
958  end if
959  end do
960  else
961  ! Skip the entries of rates that are irrelevant
962  ! because the nucleus is not contained in the network
963  do j = 1, nchannels
964  read(file_id,'(I3, 2x, 7(E12.6,2x))')
965  end do
966  end if
967 
968  end do
969 
970  ! Say someting in the output
971  call write_data_to_std_out('Neutrino reactions on (A,Z)',int_to_str(nreactions))
972 
973  ! Debug statement, TODO: Make this within verbose level
974  ! do i=1, nreactions
975  ! write(44,*) nurate_string(nunuc(i))
976  ! end do
977 
978  ! Close the file
979  close(file_id)
980 
981 end subroutine read_reactions_sieverding
982 
983 
984 
985 !> This function returns a string with the reaction information
986 !!
987 !! The string starts with the kind of reaction
988 !! (1: cc with nue, 2: cc wit anue, 3: nc with nux, 4: nc with anux)
989 !! followed by the reactant and the products seperated by "=>".
990 !!
991 !! The function is only used for debugging purposes.
992 !!
993 !! @author Moritz Reichert
994 !! @date 12.02.2023
995 function nurate_string(nurate) result(reaction_string)
997  use benam_class, only: get_net_name
998  type(nurate_type), intent(in) :: nurate
999 
1000 
1001  character(50) :: reaction_string
1002  integer :: i
1003  logical :: s_prod
1004 
1005  reaction_string = "("//int_to_str(nurate%kind)//") "//&
1006  trim(adjustl(net_names(nurate%parts(1))))
1007 
1008  do i =2, 6
1009  s_prod = .false.
1010  ! Make a cut between educts and products
1011  if (i .eq. 2) then
1012  reaction_string = trim(adjustl(reaction_string))//" =>"
1013  s_prod = .true.
1014  end if
1015 
1016  ! Write the names of the isotopes
1017  if (nurate%parts(i) .ne. 0) then
1018  if (.not. s_prod) then
1019  reaction_string = trim(adjustl(reaction_string))//" + "//&
1020  int_to_str(nurate%ch_amount(i))//" "//&
1021  trim(adjustl(get_net_name(nurate%parts(i))))
1022  else
1023  reaction_string = trim(adjustl(reaction_string))//" "//&
1024  int_to_str(nurate%ch_amount(i))//" "//&
1025  trim(adjustl(get_net_name(nurate%parts(i))))
1026  end if
1027  end if
1028 
1029  end do
1030 
1031  return
1032 
1033 
1034 end function nurate_string
1035 
1036 
1037 
1038 
1039 
1040 !> Read the channels from a file in the format of Sieverding et al 2018
1041 !!
1042 !! This subroutine reads in the channels from a file in the format of
1043 !! Sieverding et al 2018. The file is read in line by line and the
1044 !! information is stored in the global variable nuchannels.
1045 !!
1046 !! An example of the file looks like:
1047 !! \file{
1048 !! id type particle emission
1049 !! \n
1050 !! 001 nue (cc) 0p 0n 0a
1051 !! 002 nue (cc) 1p 0n 0a
1052 !! 003 nue (cc) 0p 1n 0a
1053 !! 004 nue (cc) 0p 0n 1a
1054 !! 005 nue (cc) 2p 0n 0a
1055 !! ...}
1056 !! where the type "cc" stands for charged current and "nc" for neutral
1057 !! current. The particle emission is the number of particles emitted
1058 !! in the reaction. The first line is a header line and is ignored.
1059 !!
1060 !! @see [Sieverding et al 2018](https://iopscience.iop.org/article/10.3847/1538-4357/aadd48),
1061 !! \ref read_reactions_sieverding
1062 !!
1063 !! @author M. Reichert
1064 !! @date 12.02.2023
1065 subroutine read_channels(channel_file_path)
1067  implicit none
1068  character(len=*), intent(in) :: channel_file_path !< path to the channel file
1069  integer :: nchannels !< amount of channels
1070  integer :: id !< channel id
1071  character(len=6) :: nutype !< neutrino type string (nue, nuebar, nux, nuxbar)
1072  character(len=2) :: reac_type !< reaction type string (cc or nc)
1073  integer :: dec_p !< amount of protons 0, +1, or -1
1074  integer :: amount_p !< amount of protons released
1075  integer :: amount_n !< amount of neutrons released
1076  integer :: amount_a !< amount of alpha particles released
1077  integer :: type_id !< Neutrino reaction type
1078  integer :: filename_id !< file id
1079  integer :: i !< loop variable
1080  integer :: stat !< status variable
1081 
1082  ! Open the file and get the id
1083  filename_id= open_infile(channel_file_path)
1084 
1085  ! Count the amount of channels / lines in the file
1086  nchannels = 0
1087  ! Skip the header of the file
1088  read(filename_id,*)
1089  read(filename_id,*)
1090  do
1091  read(filename_id,*,iostat=stat)
1092  if (stat.ne.0) exit
1093  nchannels = nchannels + 1
1094  end do
1095 
1096  ! Allocate the array
1097  allocate(nu_channels(nchannels), stat=stat)
1098  if (stat.ne.0) call raise_exception('Allocation of "nu_channels" failed.', &
1099  "read_channels", 330001)
1100 
1101  ! Read the file again and store the information
1102  rewind(filename_id)
1103  read(filename_id,*)
1104  read(filename_id,*)
1105 
1106  do i=1,nchannels
1107  read(filename_id,"(i3,x,a6,2x,a2,3x,i1,2x,i1,2x,i1)",iostat=stat) &
1108  id, nutype, reac_type, amount_p, amount_n, amount_a
1109  if (stat.ne.0) exit
1110 
1111  ! Check that everything is read in correctly
1112  if (i .ne. id) then
1113  call raise_exception("Channel id does not match the line number. "// &
1114  "Expected: "//int_to_str(i)//", got: "//int_to_str(id)//".", &
1115  "read_channels", 330006)
1116  end if
1117 
1118  ! Charged current reaction
1119  if (reac_type.eq."cc") then
1120  if (trim(adjustl(nutype)).eq."nue") then
1121  type_id = 1
1122  dec_p = -1
1123  elseif (trim(adjustl(nutype)).eq."nuebar") then
1124  type_id = 2
1125  dec_p = 1
1126  else
1127  call raise_exception("Unknown neutrino type in nu_channels file. "// &
1128  "Only 'nue' and 'nuebar' are allowed for CC reactions. "// &
1129  "Got: '"//trim(adjustl(nutype))//"'.", &
1130  "read_channels", 330003 )
1131  end if
1132  ! Neutral current reaction
1133  else if (reac_type.eq."nc") then
1134  if (trim(adjustl(nutype)).eq."nux") then
1135  type_id = 3
1136  dec_p = 0
1137  elseif (trim(adjustl(nutype)).eq."nuxbar") then
1138  type_id = 4
1139  dec_p = 0
1140  else
1141  call raise_exception("Unknown neutrino type in nu_channels file. "// &
1142  "Only 'nux' and 'nuxbar' are allowed for NC reactions. "// &
1143  "Got: '"//trim(adjustl(nutype))//"'.", &
1144  "read_channels", 330003 )
1145  end if
1146  else
1147  call raise_exception("Unknown reaction type in nu_channels file. "// &
1148  "Only 'cc' and 'nc' are allowed. "// &
1149  "Got: '"//trim(adjustl(reac_type))//"'.", &
1150  "read_channels", 330004 )
1151  end if
1152 
1153  ! Store the information
1154  nu_channels(i)%id = id
1155  nu_channels(i)%type = type_id
1156  nu_channels(i)%n_n = amount_n ! Released neutrons
1157  nu_channels(i)%n_p = amount_p ! Released protons
1158  nu_channels(i)%n_a = amount_a ! Released alphas
1159  ! Difference of protons and mass number in the products
1160  nu_channels(i)%Zdiff = amount_p+dec_p
1161  nu_channels(i)%Adiff = amount_n+amount_p+amount_a*4
1162  end do
1163 
1164  ! Close the file
1165  close(filename_id)
1166 
1167 end subroutine read_channels
1168 
1169 
1170 
1171 
1172 !>
1173 !! Reads neutrino-nuclei reaction file
1174 !!
1175 !! This subroutine reads in neutrino reactions depending on the
1176 !! input typ. The type of the call is dependent on parameter_class::nuflag.
1177 !! For nuflag = 1, this subroutine is called with typ 1 only, for e.g.,
1178 !! nuflag = 2 it is called 3 times with types 1, 2, and 3.
1179 !!
1180 !! <table>
1181 !! <caption id="multi_row">typ translation</caption>
1182 !! <tr><th> typ <th> Example filename <th> Meaning
1183 !! <tr><td> 1 <td> _neunucleons.dat_ <td> Reads (anti-)neutrino reactions on neutrons and protons
1184 !! <tr><td> 2 <td> _neunuclei.dat_ <td> Reads neutrino reactions on nuclei
1185 !! <tr><td> 3 <td> _aneunuclei.dat_ <td> Reads Antineutrino reactions on nuclei
1186 !! </table>
1187 !! The file _neunucleons.dat_ looks like:
1188 !! \file{
1189 !! n p nen
1190 !! 12.37 18.61 23.85 36.32 58.26 89.82 139.06
1191 !! p n nebp
1192 !! 6.96 11.14 14.63 22.82 36.66 55.40 82.45 }
1193 !!
1194 !! The file _neunuclei.dat_:
1195 !!
1196 !! \file{
1197 !! Cross sections for (nue,e-) reactions on nuclei for alpha=0.0
1198 !! \=============================================================
1199 !! \n
1200 !! T [MeV] 2.8 3.5 4.0 5.0 6.4 8.0 10.0
1201 !! \n
1202 !! N = 2 Z = 2 (4He )
1203 !! Integrated 0.00 0.01 0.03 0.15 0.71 2.50 7.91
1204 !! ... }
1205 !!
1206 !! and the file _aneunuclei.dat_:
1207 !!
1208 !! \file{
1209 !! T [MeV] 2.8 3.5 4.0 5.0 6.4 8.0 10.0
1210 !! \n
1211 !! N = 2 Z = 2 (4He )
1212 !! Integrated 0.00 0.01 0.02 0.09 0.41 1.29 3.64
1213 !! ...}
1214 !!
1215 !!
1216 !! @returns Array of neutrino reactions, depending on input typ either
1217 !! global_class::nurate (typ 1), global_class::nunuc (typ 2),
1218 !! or global_class::anunuc (typ 3).
1219 !!
1220 !! @see [Bruenn et al. 2002](https://arxiv.org/pdf/astro-ph/0211404.pdf),
1221 !! [Froehlich et al. 2006](https://ui.adsabs.harvard.edu/abs/2006ApJ...637..415F/abstract)
1222 !! [Langanke & Kolbe 2001](https://ui.adsabs.harvard.edu/abs/2001ADNDT..79..293L/abstract)
1223 !!
1224 !! \b Edited:
1225 !! - 12.01.14
1226 !! - 23.01.21, MR - moved it from network_init_module
1227 !!
1228 !! @remark This routine is used to read the reactions on nucleons only (typ 1).
1229 !! .
1230 subroutine readnucs(nufile,typ)
1231  use global_class, only: nurate, nurate_type
1232  use benam_class , only: benam, ident
1234  implicit none
1235 
1236  integer, intent(in) :: nufile !< neutrino cross section file unit
1237  integer, intent(in) :: typ !< type of nu-reaction: 1 -> nu/anu on n/p;
1238  !! 2 -> nu on nuclide;
1239  !! 3 -> anu on nuclide.
1240  !
1241  integer :: i
1242  integer :: stat
1243  integer :: len
1244  integer :: err
1245  character(5), dimension(2) :: nam
1246  integer, dimension(2) :: parts,ind
1247  real(r_kind), dimension(nt_nugrid) :: cs
1248  type(nurate_type), dimension(:), allocatable :: nuc_tmp
1249 
1250 
1251 !----- determine approximate number of entries in file for typ=2 or 3
1252  if (typ.ne.1) then
1253  len=1
1254  do
1255  read(nufile,'(2/)',iostat=stat)
1256  if (stat.ne.0) exit
1257  len = len+1
1258  end do
1259  allocate(nuc_tmp(len))
1260  rewind(nufile)
1261  end if
1262 !----- read nufile for the different cases
1263  select case(typ)
1264  case(1) ! only nu on n,p
1265  allocate(nurate(2))
1266  do i=1,2
1267  nurate(i)%parts(:) = 0
1268  read(nufile,111)nam(1:2),nurate(i)%source,nurate(i)%cs(1:nt_nugrid),nurate(i)%avE(1:nt_nugrid)
1269  nurate(i)%parts(1) = benam(nam(1))
1270  nurate(i)%parts(2) = benam(nam(2))
1271  nurate(i)%ch_amount(:) = 0
1272  nurate(i)%ch_amount(1) = -1
1273  nurate(i)%ch_amount(2) = 1
1274  end do
1275  case(2) ! nu on nuclides
1276  read(nufile,'(3/)')
1277  i=0
1278  do
1279  read(nufile,112,iostat=stat)parts(1:2),cs(1:nt_nugrid)
1280  if(stat.ne.0) exit
1281  call ident(parts(2),parts(1),parts(2)+1,parts(1)-1 &
1282  ,nam(1),nam(2),ind(1),ind(2),err)
1283  if (err.eq.0) then
1284  i = i+1
1285  nuc_tmp(i)%parts(:) = 0
1286  nuc_tmp(i)%parts(1:2) = ind
1287  nuc_tmp(i)%ch_amount(:) = 0
1288  nuc_tmp(i)%ch_amount(1) = -1
1289  nuc_tmp(i)%ch_amount(2) = 1
1290  nuc_tmp(i)%source = 'lznu'
1291  nuc_tmp(i)%cs = cs
1292  nuc_tmp(i)%avE = 0
1293  end if
1294  end do
1295  allocate(nunuc(i))
1296  nunuc = nuc_tmp(1:i)
1297  deallocate(nuc_tmp)
1298  call write_data_to_std_out('Neutrino reactions on (A,Z)',int_to_str(i))
1299  case(3) ! anu on nuclides
1300  read(nufile,*)
1301  i=0
1302  do
1303  read(nufile,112,iostat=stat)parts(1:2),cs(1:nt_nugrid)
1304  if(stat.ne.0) exit
1305  call ident(parts(2),parts(1),parts(2)-1,parts(1)+1 &
1306  ,nam(1),nam(2),ind(1),ind(2),err)
1307  if (err.eq.0) then
1308  i = i+1
1309  nuc_tmp(i)%parts(:) = 0
1310  nuc_tmp(i)%parts(1:2) = ind
1311  nuc_tmp(i)%ch_amount(:) = 0
1312  nuc_tmp(i)%ch_amount(1) = -1
1313  nuc_tmp(i)%ch_amount(2) = 1
1314  nuc_tmp(i)%source = 'lzan'
1315  nuc_tmp(i)%cs = cs
1316  nuc_tmp(i)%avE = 0
1317  end if
1318  end do
1319  allocate(anunuc(i))
1320  anunuc = nuc_tmp(1:i)
1321  deallocate(nuc_tmp)
1322  call write_data_to_std_out('Anti-neutrino reactions on (A,Z)',int_to_str(i))
1323  end select
1324  return
1325 
1326 111 format(5x,2a5,28x,a4/7(f6.2,4x)/7(f6.2,4x))
1327 112 format(/4x,i3,5x,i3/13x,7(f13.2))
1328 
1329 end subroutine readnucs
1330 
1331 
1332 
1333 
1334 !> Routine to merge neutrino rates into rrate array
1335 !!
1336 !! This subroutine merges the neutrino rates into a larger rate
1337 !! array via a mergesort (see \ref mergesort_module::rrate_ms)
1338 !!
1339 !! @remark This used to be done after reading chapter 2 in the reaclib
1340 !! while the reaclib file is still open. Now it is done
1341 !! afterwards which may be not as efficient, but more clear.
1342 !!
1343 !! @author M. Reichert
1344 !! @date 27.01.21
1345 subroutine merge_neutrino_rates(rrate_array,rrate_length)
1346  use error_msg_class, only: raise_exception
1347  use parameter_class, only: nuflag
1350  implicit none
1351  type(reactionrate_type),dimension(:),allocatable,intent(inout) :: rrate_array !< Large rate array, containing all reactions
1352  type(reactionrate_type),dimension(:),allocatable :: rrate_tmp !< Temporary rate array
1353  integer,intent(inout) :: rrate_length !< length of rrate_array
1354  integer :: alloc_stat !< Allocation state
1355  integer :: new_length !< New length of rrate_array
1356 
1357  if (.not. use_prepared_network) then
1358  if (nuflag .ge. 1) then
1359  new_length = rrate_length+nnu
1360  if (nnu .ne. 0) then
1361  if (.not. allocated(rrate_array)) then
1362  !-- Allocate the reaclib rate array
1363  allocate(rrate_array(nnu),stat=alloc_stat)
1364  if ( alloc_stat /= 0) call raise_exception('Allocation of "rrate_array" failed.',&
1365  "merge_neutrino_rates",330001)
1366  rrate_array(1:nnu) = rrate_nu(1:nnu)
1367  rrate_length = new_length
1368  else
1369  call rrate_sort(rrate_length,rrate_array(1:rrate_length))
1370  call rrate_ms(rrate_array(1:rrate_length),rrate_length,&
1371  rrate_nu,size(rrate_nu),0,new_length,rrate_tmp)
1372  rrate_length = new_length
1373  ! Reallocate rrate_array with new length
1374  if (allocated(rrate_array)) deallocate(rrate_array)
1375  allocate(rrate_array(rrate_length),stat=alloc_stat)
1376  if ( alloc_stat /= 0) call raise_exception('Allocation of "rrate_array" failed.',&
1377  "merge_neutrino_rates",330001)
1378  rrate_array(1:rrate_length) = rrate_tmp(1:rrate_length)
1379  end if
1380  !-- Deallocate the reaclib rate array
1381  deallocate(rrate_nu)
1382  end if
1383  end if
1384  end if
1385 
1386 end subroutine merge_neutrino_rates
1387 
1388 
1389 
1390 
1391 !> Set the type of a neutrino reaction
1392 !!
1393 !! This subroutine modifies the "kind" entry in global_class::nurate
1394 !! based on the neutrino labels. It is only called for
1395 !! reactions in the format of Froehlich et al. 2006 and
1396 !! for neutrino reactions on nucleons.
1397 !! The different kinds of neutrino reactions are:
1398 !!
1399 !! <table>
1400 !! <caption id="multi_row">Neutrino reaction types</caption>
1401 !! <tr><th> kind <th> Explanation
1402 !! <tr><td> 1 <td> Electron neutrino reaction
1403 !! <tr><td> 2 <td> Electron anti-neutrino reaction
1404 !! <tr><td> 3 <td> Muon/tau neutrino reaction
1405 !! <tr><td> 4 <td> Muon/tau anti-neutrino reaction
1406 !! </table>
1407 !! Kind 3 and 4 are not implemented at the moment.
1408 !!
1409 !! @warning This subroutine uses the neutrino reaction labels
1410 !! nen, lznu, nebp, and lzan hard coded. It is only used for
1411 !! neutrino reactions on nucleons.
1412 subroutine set_nutype(nnu_in)
1413 
1414  use global_class, only: nurate
1415 
1416  implicit none
1417  integer, intent(in) :: nnu_in !< Length of global_class::nurate
1418  character(4),dimension(4) :: nutypes
1419  integer :: i,j
1420 
1421  nutypes = (/' nen' , &
1422  'lznu' , &
1423  'nebp' , &
1424  'lzan' /)
1425  do i=1,nnu_in
1426  do j=1,4
1427  if(nurate(i)%source == nutypes(j))then
1428  if (j.le.2) then
1429  nurate(i)%kind = 1
1430  else if (j.gt.2) then
1431  nurate(i)%kind = 2
1432  end if
1433  cycle
1434  end if
1435  end do
1436  end do
1437 
1438  return
1439 
1440 end subroutine set_nutype
1441 
1442 end module nuflux_class
nuflux_class::write_reac_verbose_out
subroutine, private write_reac_verbose_out()
Write the amount of individual reactions to the out.
Definition: nuflux_class.f90:592
nuflux_class::nlumxbar
real(r_kind), dimension(:), allocatable, public nlumxbar
(anti-)mu and tau neutrino number luminosities from trajectory
Definition: nuflux_class.f90:92
parameter_class::lxbar
character(max_fname_len) lxbar
Muon and Tauon antineutrino luminosities [erg/s].
Definition: parameter_class.f90:195
nuflux_class::init_nuflux
subroutine, public init_nuflux()
Initialize nuflux module.
Definition: nuflux_class.f90:126
nuflux_class::anunuc
type(nurate_type), dimension(:), allocatable, private anunuc
anti-neutrino reactions on nuclides
Definition: nuflux_class.f90:73
parameter_class::use_prepared_network
logical use_prepared_network
Use a prepared folder with all necessary data in binary format.
Definition: parameter_class.f90:94
global_class::net_names
character *5, dimension(:), allocatable, public net_names
list of isotopes contained in the network
Definition: global_class.f90:95
nuflux_class::tnuxbar
real(r_kind), dimension(:), allocatable, public tnuxbar
(anti-)mu and tau neutrino temperatures from trajectory
Definition: nuflux_class.f90:90
global_class::ipro
integer, public ipro
index of alphas, neutrons and protons
Definition: global_class.f90:94
nuflux_class::nucs
subroutine, public nucs()
Interpolate neutrino cross sections.
Definition: nuflux_class.f90:399
global_class::reactionrate_type
reaction rate type
Definition: global_class.f90:44
nuflux_class::rs
real(r_kind), private rs
Schwarzschild radius for M=mns [km], calculated in init_nuflux.
Definition: nuflux_class.f90:70
inter_module
Module inter_module with interpolation routines.
Definition: inter_module.f90:13
nuflux_class::n_nuclei
integer, private n_nuclei
Definition: nuflux_class.f90:95
nuflux_class::sigtempnu
real(r_kind), dimension(nt_nugrid), private sigtempnu
temperature grid for neutrino cross sections
Definition: nuflux_class.f90:64
parameter_class::enuebar
character(max_fname_len) enuebar
average electron-antineutrino energies [MeV]
Definition: parameter_class.f90:193
nuflux_class::tnuebar
real(r_kind), dimension(:), allocatable, public tnuebar
(anti-)electron neutrino temperatures from trajectory
Definition: nuflux_class.f90:89
benam_class::findaz
integer function, public findaz(ai, zi)
Finds an isotope index in the network table, given its A and Z. In case it was not found,...
Definition: benam_class.f90:887
nuflux_class::merge_neutrino_rates
subroutine, public merge_neutrino_rates(rrate_array, rrate_length)
Routine to merge neutrino rates into rrate array.
Definition: nuflux_class.f90:1346
nuflux_class::calculate_nu_rate
subroutine, public calculate_nu_rate(rrate, rat_calc)
Calculates the cross section times the neutrino flux.
Definition: nuflux_class.f90:336
nuflux_class::nutemp
subroutine, public nutemp(time)
Calculates (anti-) neutrino temperatures.
Definition: nuflux_class.f90:502
nuflux_class::set_nutype
subroutine, private set_nutype(nnu_in)
Set the type of a neutrino reaction.
Definition: nuflux_class.f90:1413
nuflux_class::nlumebar
real(r_kind), dimension(:), allocatable, public nlumebar
(anti-)electron neutrino number luminosities from trajectory
Definition: nuflux_class.f90:91
error_msg_class
Error handling routines.
Definition: error_msg_class.f90:16
global_class::ihe4
integer, public ihe4
Definition: global_class.f90:94
benam_class::benam
integer function, public benam(name)
Returns the index number of isotope 'name'.
Definition: benam_class.f90:251
nuflux_class::nu_channel_type
Channel type for neutrino reactions according to Sieverding et al. 2018
Definition: nuflux_class.f90:27
nuflux_class::readnucs
subroutine readnucs(nufile, typ)
Reads neutrino-nuclei reaction file.
Definition: nuflux_class.f90:1231
nuflux_class::tnue
real(r_kind), dimension(:), allocatable, public tnue
Definition: nuflux_class.f90:89
nuflux_class::include_nc_reactions
logical, private include_nc_reactions
Flag to include neutrino reactions that are not charged current.
Definition: nuflux_class.f90:94
error_msg_class::int_to_str
character(:) function, allocatable, public int_to_str(num)
Converts a given integer to a string.
Definition: error_msg_class.f90:224
nuflux_class::output_binary_neutrino_reaction_data
subroutine, public output_binary_neutrino_reaction_data(path)
Write the reactions to a file in binary format.
Definition: nuflux_class.f90:774
error_msg_class::raise_exception
subroutine, public raise_exception(msg, sub, error_code)
Raise a exception with a given error message.
Definition: error_msg_class.f90:245
mergesort_module::rrate_ms
subroutine, public rrate_ms(x, xs, y, ys, r, ptz, rate_out)
Merges two tables of rates (of type global_class::reactionrate_type).
Definition: mergesort_module.f90:227
nuflux_class::n_anuclei
integer, private n_anuclei
Definition: nuflux_class.f90:95
nuflux_class::n_nucleo
integer, private n_nucleo
Definition: nuflux_class.f90:95
parameter_class::enux
character(max_fname_len) enux
average Muon and Tauon neutrino energies [MeV]
Definition: parameter_class.f90:196
parameter_class::neutrino_mode
character(max_fname_len) neutrino_mode
Similar to trajectory mode.
Definition: parameter_class.f90:185
global_class::nurate_type
data fields for neutrino rates given in Langanke&Kolbe 2001
Definition: global_class.f90:70
parameter_class::max_fname_len
integer, parameter, public max_fname_len
maximum length of filenames
Definition: parameter_class.f90:58
nuflux_class::nurate_string
character(50) function nurate_string(nurate)
This function returns a string with the reaction information.
Definition: nuflux_class.f90:996
global_class::ineu
integer, public ineu
Definition: global_class.f90:94
nuflux_class::read_binary_neutrino_reaction_data
subroutine, private read_binary_neutrino_reaction_data(path)
Read the reactions from a file in binary format.
Definition: nuflux_class.f90:736
global_class::isotope
type(isotope_type), dimension(:), allocatable, public isotope
all nuclides used in the network
Definition: global_class.f90:34
error_msg_class::write_data_to_std_out
subroutine, public write_data_to_std_out(str_msg, value_str, unit)
Write data to the standard output (usually OUT)
Definition: error_msg_class.f90:122
nuflux_class::nlume
real(r_kind), dimension(:), allocatable, public nlume
Definition: nuflux_class.f90:91
hydro_trajectory::ztime
real(r_kind), dimension(:), allocatable, public ztime
time information from trajectory
Definition: hydro_trajectory.f90:19
nuflux_class
Contains variables and parameters related to neutrino fluxes.
Definition: nuflux_class.f90:14
nuflux_class::fluxnu
real(r_kind), dimension(4), public fluxnu
Neutrino fluxes This variable is calculated and set in nuflux. The dimension 4 accounts for the diffe...
Definition: nuflux_class.f90:45
nuflux_class::nnu
integer nnu
Amount of neutrino reactions.
Definition: nuflux_class.f90:39
parser_module
Subroutines for equation parsing in case of an analytic trajectory or luminosity mode.
Definition: parser_module.f90:22
global_class::nurate
type(nurate_type), dimension(:), allocatable, public nurate
neutrino rates
Definition: global_class.f90:81
nuflux_class::nu_channels
type(nu_channel_type), dimension(:), allocatable nu_channels
Array of neutrino channels.
Definition: nuflux_class.f90:37
mergesort_module::rrate_sort
subroutine, public rrate_sort(num, rate_array)
Sorts chapter one of the rate array.
Definition: mergesort_module.f90:676
parameter_class::nuchannel_file
character(max_fname_len) nuchannel_file
Contains neutrino channel information as in Sieverding et al. 2018.
Definition: parameter_class.f90:175
parser_module::parse_string
real(r_kind) function, public parse_string(input_string, var_value)
Takes a string and evaluates the expression.
Definition: parser_module.f90:807
parameter_class::le
character(max_fname_len) le
electron-neutrino luminosities [erg/s]
Definition: parameter_class.f90:190
nuflux_class::read_reactions_sieverding
subroutine, private read_reactions_sieverding(reaction_file_path, reactype)
Read the reactions from a file in the format of Sieverding et al 2018.
Definition: nuflux_class.f90:817
parameter_class::unit
type(unit_type), public unit
constants and unit conversion factors
Definition: parameter_class.f90:54
rrs_nu
#define rrs_nu
Definition: macros.h:51
parameter_class::nunucleo_rates_file
character(max_fname_len) nunucleo_rates_file
neutrino reaction rates on nucleons
Definition: parameter_class.f90:174
nuflux_class::read_channels
subroutine read_channels(channel_file_path)
Read the channels from a file in the format of Sieverding et al 2018.
Definition: nuflux_class.f90:1066
file_handling_class
Provide some basic file-handling routines.
Definition: file_handling_class.f90:18
nuflux_class::n_cc
integer, private n_cc
Definition: nuflux_class.f90:95
nuflux_class::lumin_debugfile
integer, private lumin_debugfile
Debug file to write neutrino luminosities, neutrinospheres, and temperatures.
Definition: nuflux_class.f90:78
r_kind
#define r_kind
Definition: macros.h:46
nuflux_class::rrate_nu
type(reactionrate_type), dimension(:), allocatable rrate_nu
Neutrino rate array.
Definition: nuflux_class.f90:41
hydro_trajectory::zsteps
integer zsteps
number of timesteps in the hydro trajectory
Definition: hydro_trajectory.f90:17
hydro_trajectory
Contains arrays representing thermodynamic conditions from hydro trajectory file.
Definition: hydro_trajectory.f90:14
nuflux_class::nt_nugrid
integer, parameter nt_nugrid
Length of the neutrino rate grid.
Definition: nuflux_class.f90:62
nuflux_class::n_nc
integer, private n_nc
Definition: nuflux_class.f90:95
nuflux_class::tempnu
real(r_kind), dimension(4), private tempnu
Neutrino temperatures. This variable is set in nutemp either from the values of a trajectory or from ...
Definition: nuflux_class.f90:53
file_handling_class::open_infile
integer function, public open_infile(file_name)
Same for reading (input file)
Definition: file_handling_class.f90:126
nuflux_class::nu_binary_name
character(len= *), parameter, private nu_binary_name
Name of the neutrino binary file.
Definition: nuflux_class.f90:98
file_handling_class::open_outfile
integer function, public open_outfile(file_name)
Shorthand for opening a new file for writing (output file)
Definition: file_handling_class.f90:108
global_class
Contains types and objects shared between multiple modules.
Definition: global_class.f90:19
benam_class::get_net_name
character(:) function, allocatable, public get_net_name(index, trimmed)
Getter of net_names, translating indices to a nucleus name.
Definition: benam_class.f90:280
nuflux_class::read_neutrino_rates
subroutine, private read_neutrino_rates()
Read neutrino reactions and fill the global_class::nurate array.
Definition: nuflux_class.f90:633
parameter_class::enue
character(max_fname_len) enue
average electron-neutrino energies [MeV]
Definition: parameter_class.f90:192
file_handling_class::open_unformatted_outfile
integer function, public open_unformatted_outfile(file_name)
Shorthand for opening a new unformatted file for writing (output file)
Definition: file_handling_class.f90:74
parameter_class::lebar
character(max_fname_len) lebar
electron-antineutrino luminosities [erg/s]
Definition: parameter_class.f90:191
benam_class::ident
subroutine, public ident(z1, n1, z2, n2, nam1, nam2, ind1, ind2, err)
Identifies the nuclide names and indices corresponding to z,n combinations (z1,n1),...
Definition: benam_class.f90:1039
nuflux_class::nlumx
real(r_kind), dimension(:), allocatable, public nlumx
Definition: nuflux_class.f90:92
file_handling_class::open_unformatted_infile
integer function open_unformatted_infile(file_name)
Open an unformatted file for reading.
Definition: file_handling_class.f90:89
parameter_class::nuflag
integer nuflag
defines type of neutrino reactions used
Definition: parameter_class.f90:85
parameter_class::nurates_file
character(max_fname_len) nurates_file
Neutrino reactions on heavy nuclei as in Sieverding et al. 2018.
Definition: parameter_class.f90:176
mergesort_module
Module mergesort_module for merging arrays of rates.
Definition: mergesort_module.f90:16
nuflux_class::nunuc
type(nurate_type), dimension(:), allocatable, private nunuc
neutrino reactions on nuclides
Definition: nuflux_class.f90:74
parameter_class::prepared_network_path
character(max_fname_len) prepared_network_path
Prepared network folder.
Definition: parameter_class.f90:198
parameter_class::enuxbar
character(max_fname_len) enuxbar
average Muon and Tauon antineutrino energies [MeV]
Definition: parameter_class.f90:197
nuflux_class::nuflux
subroutine, public nuflux(time, rkm)
Determines neutrino flux for current time (in units of cm^-2 s^-1).
Definition: nuflux_class.f90:177
parameter_class::lx
character(max_fname_len) lx
Muon and Tauon neutrino luminosities [erg/s].
Definition: parameter_class.f90:194
rrt_nu
#define rrt_nu
Definition: macros.h:77
parameter_class
Contains all runtime parameters as well as phys and math constants.
Definition: parameter_class.f90:24
benam_class::getcoefficients
subroutine, public getcoefficients(rate_array, length_rate_array)
Returns the 1/n! factor where n is the number of equal isotopes entering a reaction....
Definition: benam_class.f90:307
mergesort_module::nurate_ms
subroutine, public nurate_ms(x, xs, y, ys, r)
Merges two tables of neutrino rates (of type global_class::nurate_type).
Definition: mergesort_module.f90:88
nuflux_class::tnux
real(r_kind), dimension(:), allocatable, public tnux
Definition: nuflux_class.f90:90
benam_class
Subroutines needed to initialise the network.
Definition: benam_class.f90:11