readini.f90
Go to the documentation of this file.
1 !> @file readini.f90
2 !!
3 !! The error file code for this file is ***W39***.
4 !!
5 !! Contains the module \ref readini
6 !!
7 
8 !> Subroutines for initialization and parameter parsing.
9 !!
10 !! The module is responsible for reading several input files
11 !! such as initial seeds via \ref read_seed_urs or the hydrodynamic trajectory
12 !! via \ref custom_read
13 !!
14 #include "macros.h"
15 module readini
17  use error_msg_class
21  implicit none
22 
23  ! Only make necessary routines public
29 
30  contains
31 
32 !>
33 !! Initialize the readini module and open files.
34 !!
35 !! Depending on user defined parameters
36 !! (e.g., \ref parameter_class::custom_snapshots)
37 !! this subroutine calls several subroutines to read
38 !! input files. After reading the files, it calls
39 !! \ref consistency_check to make a couple of checks and
40 !! raise an error if something is not correct.
41 !!
42 !! @author: Moritz Reichert
43 !!
44 !! \b Edited: 28.02.17
45 subroutine readini_init()
46  implicit none
47 
48  ! read trajectory
49  if (trim(trajectory_mode).EQ.'from_file') then
50  call custom_read()
51  end if
52 
53  ! Custom snapshots
56  end if
57 
58  ! Read the tracked nuclei
59  if ((track_nuclei_every .gt. 0) .or. (h_track_nuclei_every .gt. 0)) then
60  call read_track_nuclei()
61  end if
62 
63  ! Check for consistency
64  call consistency_check()
65 
66 
67 end subroutine readini_init
68 
69 
70 
71 !>
72 !! @brief Read in times for snapshots.
73 !!
74 !! These times should be given by a separate file
75 !! with the parameter \ref parameter_class::custom_snapshots.
76 !! The units in this file is days. The subroutines that are based on
77 !! the custom snapshots assume a sorted time array and it is therefore
78 !! sorted in the end of this subroutine. An example of the file could be:
79 !! \file{
80 !! 1.1574074074074073e-04
81 !! 0.0208333
82 !! 1 }
83 !! This would output a snapshot at 10 s, 30 min, and 1 day.
84 !!
85 !! @see timestep_module::restrict_timestep, analysis::output_iteration
86 !!
87 !! @author Moritz Reichert
88 !!
92  implicit none
93  integer :: c_snapshots !< File id
94  integer :: rstat !< Reading status
95  integer :: file_length !< Amount of lines of the file
96  integer :: i !< Loop variable
97  logical :: sorted !< For bubblesort
98  real(r_kind) :: helper !< Storage for sorting array
99 
100  ! Open the file
101  c_snapshots= open_infile(snapshot_file)
102 
103  ! Get the length of the file
104  file_length = 0
105  do
106  read(c_snapshots,*,iostat=rstat)
107  if (rstat .ne. 0)exit
108  file_length = file_length + 1
109  end do
110 
111  ! Allocate Array
112  allocate(snapshot_time(file_length),stat=rstat)
113  if (rstat /= 0) call raise_exception('Allocation of "snapshot_time" failed.',"read_custom_snapshots",&
114  390001)
115  ! Rewind the file to read it again
116  rewind(c_snapshots)
117 
118  ! Read the file again
119  do i=1,file_length
120  read(c_snapshots,*,iostat=rstat) snapshot_time(i)
121  if (rstat .ne. 0) call raise_exception("Unable to read custom snapshots."//new_line("A")//&
122  'Check the input file given with the parameter "snapshot_file".',&
123  "read_custom_snapshots",&
124  390003)
125  snapshot_time(i) = snapshot_time(i)*24.*60.*60. ! Convert Days -> Seconds
126  end do
127 
128  ! Store also length of the array
129  snapshot_amount = file_length
130  ! Bubblesort to ensure array is sorted
131  ! It is also the fastest way for already sorted arrays
132  sorted = .false.
133  do while (.not. sorted)
134  sorted = .true.
135  ! Sort the array. Use Bubblesort
136  do i=1,file_length-1
137  if (snapshot_time(i+1) .lt. snapshot_time(i)) then
138  ! Swap entries
139  helper = snapshot_time(i+1)
140  snapshot_time(i+1) = snapshot_time(i)
141  snapshot_time(i) = helper
142  sorted = .false.
143  end if
144  end do
145  end do
146 
147  ! Close the file again
148  call close_io_file(c_snapshots,snapshot_file)
149  return
150 
151 end subroutine read_custom_snapshots
152 
153 
154 
155 
156 
157 
158 !>
159 !! @brief Reads in nuclei that will be tracked and where the abundance will
160 !! be stored in a separate file.
161 !!
162 !! If parameter_class::track_nuclei_every is larger than 0,
163 !! a file will be created, containing the information of the abundances of the nuclei.
164 !! This is based on the input parameter \ref parameter_class::track_nuclei_file
165 !! that contains a path to a file with the format of the nuclei being the same
166 !! as the format of the sunet file. An example could be:
167 !! \file{
168 !! c13
169 !! ti44
170 !! ni56 }
171 !!
172 !! @note Verbose level greater than 2 will create the file _debug_track_nuclei.dat_
173 !! to debug this subroutine.
174 !!
175 !! @author Moritz Reichert
176 !!
177 !! \b Edited:
178 !! - 09.06.17
179 !! .
180 subroutine read_track_nuclei()
183  use benam_class, only: benam
184  implicit none
185  integer :: track_id !< File ID
186  integer :: istat !< Status of reading and allocation
187  integer :: i !< Loop variable
188  integer :: i_tmp !< temporary index of the loop
189  integer :: file_length !< Loop variable
190  integer :: ind_tmp !< Temporary index of the read nucleus
191  integer :: debug_track !< File ID of debug file
192  character*5 :: nam_tmp !< Temporary name
193 
194  info_entry("read_track_nuclei")
195 
196  ! Debugging
197  if (verbose_level .gt. 2) then
198  ! Open debug file and write a header for the subroutine variance (???)
199  debug_track = open_outfile('debug_track_nuclei.dat')
200  write(debug_track,'(A)') &
201  '# Debugging info for read_track_nuclei() from readini.f90'
202  write(debug_track,'("Opened File: ",A)') track_nuclei_file
203  end if
204 
205  ! Amount of nuclei to track
206  track_nuclei_nr = 0
207  ! File length can be larger, nuclei are not necessary contained in the list
208  file_length = 0
209 
210  ! Open the file
211  track_id= open_infile(track_nuclei_file)
212 
213  do ! determine the number tracked nuclei
214  read(track_id,'(a5)',iostat=istat) nam_tmp
215  if (istat .ne. 0)exit
216 
217  ind_tmp = benam(nam_tmp)
218  ! Check that the nucleus is also contained, otherwise don't track it
219  if (ind_tmp .ne. 0) track_nuclei_nr= track_nuclei_nr + 1
220  file_length = file_length + 1
221  end do
222 
223  ! Allocate the array that will contain the indices of the nuclei
224  allocate(track_nuclei_indices(track_nuclei_nr),stat=istat)
225  if (istat /= 0) call raise_exception('Allocation of "track_nuclei_indices" failed.',"read_track_nuclei",&
226  390001)
227 
228  ! start at the beginning of the file
229  rewind(track_id)
230 
231  ! Index of the array
232  i_tmp = 1
233  ! Read the nuclei and store the index
234  do i=1,file_length
235  read(track_id,'(a5)',iostat=istat)nam_tmp
236  ! Get the index of the nucleus
237  ind_tmp = benam(nam_tmp)
238 
239  if (verbose_level .gt. 2) then
240  !Track which nucleus is read
241  write(debug_track,'("Reading",A,7x,"Index: ",I10)') nam_tmp,ind_tmp
242  end if
243  ! write it to the array
244  if (ind_tmp .ne. 0) then
245  track_nuclei_indices(i_tmp) = ind_tmp
246  i_tmp = i_tmp +1
247  else
248  ! Say something if there is a nucleus that is not known
249  if (verbose_level .gt. 2) then
250  write(debug_track,'("Nucleus",2x,A,2x,"is not contained in network")') nam_tmp
251  end if
252  end if
253  end do
254 
255  ! Close everything again
256  call close_io_file(track_id,track_nuclei_file)
257 
258  if (verbose_level .gt. 2) then
259  write(debug_track,'("Tracking ",I10," nuclei")') track_nuclei_nr
260  call close_io_file(debug_track,'debug_track_nuclei.dat')
261  end if
262 
263  info_exit("read_track_nuclei")
264 
265  return
266 end subroutine read_track_nuclei
267 
268 
269 
270 !>
271 !! @brief Reads in seed abundances from file \ref parameter_class::seed_file
272 !!
273 !! The input file can have a custom format specified by \ref parameter_class::seed_format.
274 !! For the seed_format "name X" The file would look like:
275 !! \file{
276 !! \# I'm a comment
277 !! n 2.000000e-01
278 !! p 1.000000e-01
279 !! c12 2.000000e-01
280 !! o16 3.000000e-01
281 !! ca40 1.500000e-01
282 !! tc98 0.500000e-01 }
283 !!
284 !! Note that empty lines or lines starting with "#" at the beginning of the file are skipped.
285 !! Another example for seed format "A Z X skip" looks like:
286 !! \file{
287 !! 1 0 2.000000e-01 unimportant
288 !! 1 1 1.000000e-01 unimportant
289 !! 12 6 2.000000e-01 unimportant
290 !! 16 8 3.000000e-01 unimportant
291 !! 40 20 1.500000e-01 unimportant
292 !! 98 48 0.500000e-01 unimportant }
293 !!
294 !! If the mass fractions do not sum up to one, this subroutine will rescale
295 !! them. In order to make this routine work, also
296 !! \ref parameter_class::read_initial_composition has to be set to "yes".
297 !!
298 !! @see parameter_class::seed_file, parameter_class::seed_format
299 !! @author Moritz Reichert
300 !!
301 !! @remark This subroutine replaced the previous "read_seed_urs" subroutine of
302 !! M. Ugliano.
303 !!
304 !! \b Edited:
305 !! - 01.06.22 - MR
306 !! .
307 subroutine read_seed(iniab)
309  use global_class, only: isotope,net_size
312  implicit none
313  ! The pass
314  real(r_kind),dimension(net_size),intent(out) :: iniab !< initial abundances
315  ! Internal variables
316  character(max_fname_len) :: current_col,col_name,col_unit !< Helper variables
317  character(max_fname_len) :: help_reader !< Helper variable
318  integer :: col_count !< Amount of columns
319  integer :: i,j !< Loop variable
320  integer :: a_i,z_i,n_i,x_i,y_i,name_i !< Column indices
321  integer :: seed_unit !< Seed file identifier
322  integer :: istat !< Status variable
323  integer :: skip_count !< Amount of lines skipped
324  logical :: skipping !< helper variable
325  integer :: l_file !< length of the file
326  real(r_kind) :: mafra_norm !< Mass fraction norm
327  integer,dimension(:),allocatable :: a,z,n !< Mass number, atomic number, neutron number
328  real(r_kind),dimension(:),allocatable :: y,x !< Abundance, mass fraction
329  character*5,dimension(:),allocatable :: name !< Name of nucleus
330  character(max_fname_len),dimension(:),allocatable :: row_read !< temporary array for one line
331 
332  info_entry("read_seed")
333 
334  ! Initialize all index variables
335  a_i = -1; z_i = -1; n_i = -1; x_i = -1; y_i = -1; name_i = -1
336 
337  ! Convert the custom string to lower case letters
338  do i = 1, max_fname_len
339  j = iachar(seed_format(i:i))
340  if (j>= iachar("A") .and. j<=iachar("Z") ) then
341  seed_format(i:i) = achar(iachar(seed_format(i:i))+32)
342  else
343  continue
344  end if
345  end do
346 
347  ! Get correct index from the columns and count them
348  current_col = ''
349  col_count = 0
350  do i = 2,max_fname_len
351  current_col = trim(adjustl(current_col))//seed_format(i-1:i-1)
352  if ((seed_format(i-1:i-1) .ne. ' ') .and. (seed_format(i:i) .eq. ' ')) then
353  ! Count the columns
354  col_count = col_count +1
355  ! Get the name of the column
356  col_name = ''
357  name_loop : do j=1,max_fname_len
358  if ((current_col(j:j) .eq. ':' ) .or. (current_col(j:j) .eq. ' ' )) exit name_loop
359  col_name = trim(adjustl(col_name))//current_col(j:j)
360  end do name_loop
361  ! Get the unit of the column
362  j=j+1
363  col_unit = ''
364  unit_loop : do j=j,max_fname_len
365  if ((current_col(j:j) .eq. ' ' )) exit unit_loop
366  col_unit = trim(adjustl(col_unit))//current_col(j:j)
367  end do unit_loop
368 
369  ! The column and everything is known here
370  ! Store the column index and units
371  select case (trim(adjustl(col_name)))
372  case('a')
373  a_i = col_count !index of the column (mass number)
374  case('z')
375  z_i = col_count !index of the column (proton number)
376  case('n')
377  n_i = col_count !index of the column (neutron number)
378  case('x')
379  x_i = col_count !index of the column (mass fraction)
380  case('y')
381  y_i = col_count !index of the column (abundance)
382  case('name')
383  name_i = col_count !index of the column (nucleus name)
384  case('skip')
385  continue
386  case default
387  call raise_exception('Problem when analyzing: "'//&
388  trim(adjustl(seed_format))//'". '//new_line('A')//&
389  'Can not read column "'//trim(adjustl(col_name))//'".'//&
390  new_line('A')//'Column type unknown.',"read_seeds",&
391  390021)
392  end select
393 
394  ! Clear the string for the current column
395  current_col = ''
396  end if
397  end do
398 
399  ! open the trajectory file
400  seed_unit= open_infile(seed_file)
401  ! Count how many lines to skip
402  l_file = 0
403  skip_count = 0
404  skipping = .true.
405  do ! determine the number of records
406  read(seed_unit,"(A)",iostat=istat)help_reader
407  if (istat .ne. 0)exit
408  help_reader = adjustl(help_reader) ! Move everything to the left
409 
410  ! Check if the line is to skip or not
411  if ((skipping .eqv. .true.) .and. (len_trim(help_reader) .eq. 0)) then
412  skip_count = skip_count+1
413  cycle
414  elseif ((skipping .eqv. .true.) .and. (help_reader(1:1) .eq. "#")) then
415  skip_count = skip_count+1
416  cycle
417  else
418  skipping = .false.
419  end if
420 
421  ! Check for empty lines in between
422  if ((skipping .eqv. .false.) .and. (len_trim(help_reader) .eq. 0)) then
423  if (verbose_level .gt. 1) write(*,*) "Warning, seed file ended unexpectedly."
424  exit
425  end if
426 
427  ! Count the amount of entries
428  l_file = l_file + 1
429  end do
430 
431  ! Allocate arrays
432  allocate(row_read(col_count),stat=istat)
433  if (istat /= 0) call raise_exception('allocation failed.',"read_seeds",390001)
434  allocate(a(l_file),z(l_file),n(l_file),y(l_file),x(l_file),name(l_file),stat=istat)
435  if (istat /= 0) call raise_exception('allocation failed.',"read_seeds",390001)
436 
437  ! Skip first rows
438  rewind(seed_unit)
439  do i=1,skip_count
440  read(seed_unit,*)
441  end do
442 
443  ! Initialize
444  a(:) = 0; z(:) = 0; n(:) = 0; y(:) = 0; x(:) = 0 ; name(:) = " "
445  ! Finally read the file
446  do i=1,l_file
447  read(seed_unit,*)row_read
448  if (a_i .ne. -1) a(i) = str_to_int(row_read(a_i))
449  if (z_i .ne. -1) z(i) = str_to_int(row_read(z_i))
450  if (n_i .ne. -1) n(i) = str_to_int(row_read(n_i))
451  if (y_i .ne. -1) y(i) = str_to_float(row_read(y_i))
452  if (x_i .ne. -1) x(i) = str_to_float(row_read(x_i))
453  if (name_i .ne. -1) name(i) = trim(adjustl(row_read(name_i)))
454  ! write(*,*)row_read(2)
455  end do
456 
457  ! Construct other entries
458  if ((a_i .eq. -1) .and. (z_i .ne. -1) .and. (n_i .ne. -1)) then
459  a(:) = z(:)+n(:)
460  elseif ((a_i .ne. -1) .and. (z_i .eq. -1) .and. (n_i .ne. -1)) then
461  z(:) = a(:)-n(:)
462  elseif ((a_i .ne. -1) .and. (z_i .ne. -1) .and. (n_i .eq. -1)) then
463  n(:) = a(:)-z(:)
464  elseif ((a_i .ne. -1) .and. (z_i .ne. -1) .and. (n_i .ne. -1)) then
465  continue
466  else
467  if (name_i .ne. -1) then
468  do j=1,l_file
469  iso_loop: do i=1,net_size
470  if(trim(adjustl(name(j))).eq.trim(adjustl(isotope(i)%name))) then
471  a(j) = isotope(i)%mass
472  z(j) = isotope(i)%p_nr
473  n(j) = isotope(i)%n_nr
474  exit iso_loop
475  end if
476  end do iso_loop
477  end do
478  else
479  call raise_exception("Not possible to read seeds. Columns missing!",&
480  "read_seeds",390022)
481  end if
482  end if
483 
484  ! Store abundances / mass fractions
485  if ((y_i .ne. -1) .and. (x_i .eq. -1)) then
486  x(:) = y(:)*a(:)
487  elseif ((y_i .eq. -1) .and. (x_i .ne. -1)) then
488  do i=1,l_file
489  ! Avoid division by zero, filter with sunet later
490  if (a(i) .eq. 0) a(i) = 1
491  y(i) = x(i)/a(i)
492  end do
493  elseif ((y_i .ne. -1) .and. (x_i .ne. -1)) then
494  continue
495  else
496  call raise_exception("Not possible to read seeds. Give either Y or X!",&
497  "read_seeds",390023)
498  end if
499  ! At this point, Y, X, A, Z, and N are known (or the code crashed)
500  ! Renormalize
501  mafra_norm = sum(x)
502 
503  ! Check if it is a reasonable norm
504  if (abs(mafra_norm-1d0) .gt. 0.1 ) then
505  call raise_exception("Norm of seed nuclei was terrible ("//num_to_str(abs(mafra_norm-1d0))//")! "//&
506  "Check your initial abundances or seed format!",&
507  "read_seeds",390025)
508  end if
509 
510  call write_data_to_std_out("Mass conservation pre norm",num_to_str(mafra_norm))
511  x(:) = x(:)/mafra_norm
512  y(:) = y(:)/mafra_norm
513  mafra_norm = sum(x)
514  call write_data_to_std_out("Mass conservation post norm",num_to_str(mafra_norm))
515 
516  ! Also ensure initial zero Y array
517  iniab(:) = 0
518  ! Find correct entries
519  do j=1, l_file
520  inner_loop: do i=1, net_size
521  if (name_i .ne. -1) then
522  ! Use the name as it is more unique
523  if(trim(adjustl(name(j))).eq.trim(adjustl(isotope(i)%name))) then
524  iniab(i) = y(j)
525  exit inner_loop
526  end if
527  else
528  ! Otherwise use the proton and mass number and hope for the best
529  if ((z(j) .eq. isotope(i)%p_nr) .and. (a(j) .eq. isotope(i)%mass)) then
530  iniab(i) = y(j)
531  exit inner_loop
532  end if
533  end if
534  end do inner_loop
535  end do
536 
537  ! Close the file again
538  call close_io_file(seed_unit,seed_file)
539  info_exit("read_seed")
540 
541 end subroutine read_seed
542 
543 
544 
545 !>
546 !! Function to convert from a given time unit to seconds.
547 !!
548 !! ### Example
549 !!~~~~~~~~~~~~~~.f90
550 !! b = time_unit_conversion("ms")
551 !!~~~~~~~~~~~~~~
552 !! b will be \f$ 10^{-3} \f$ as it is the conversion from ms to s.
553 !!
554 !! @note New time units can be defined here.
555 !!
556 !! @author Moritz Reichert
557 function time_unit_conversion(unit)
559  implicit none
560  character(len=*),intent(in) :: unit !< Input unit
561  real(r_kind) :: time_unit_conversion !< Conversion factor to obtain seconds
562 
563  select case (trim(adjustl(unit)))
564  case('')
566  case('s')
568  case('ms')
569  time_unit_conversion = 1.0d-3
570  case('h')
572  case('min')
574  case('yrs')
575  time_unit_conversion = 31536000
576  case default
577  call raise_exception('Problem when analyzing: "'//&
578  trim(adjustl(trajectory_format))//'". '//new_line('A')//'Time unit "'//&
579  trim(adjustl(unit))//'" unknown.',"time_unit_conversion",&
580  390004)
581  end select
582 end function time_unit_conversion
583 
584 
585 !>
586 !! Function to convert from a given temperature unit to GK
587 !!
588 !! ### Example
589 !!~~~~~~~~~~~~~~.f90
590 !! b = temp_unit_conversion("K")
591 !!~~~~~~~~~~~~~~
592 !! b will be \f$ 10^{-9} \f$ as it is the conversion from K to GK.
593 !!
594 !! @note New temperature units can be defined here.
595 !!
596 !! @author Moritz Reichert
597 function temp_unit_conversion(unit)
599  implicit none
600  character(len=*),intent(in) :: unit !< Input unit
601  real(r_kind) :: temp_unit_conversion !< Conversion factor to obtain GK
602 
603  select case (trim(adjustl(unit)))
604  case('')
606  case('-')
608  case('gk')
610  case('k')
611  temp_unit_conversion = 1.0d-9
612  case('mev')
613  temp_unit_conversion = 11.604
614  case('ev')
615  temp_unit_conversion = 11604.52*1d-9
616  case('kev')
617  temp_unit_conversion = 11604.52*1d-6
618  case default
619  call raise_exception('Problem when analyzing: "'//&
620  trim(adjustl(trajectory_format))//'". '//new_line('A')//'Temperature unit "'//&
621  trim(adjustl(unit))//'" unknown.',"temp_unit_conversion",&
622  390005)
623  end select
624 end function temp_unit_conversion
625 
626 
627 !>
628 !! Function to convert from a given density unit to g/ccm
629 !!
630 !! ### Example
631 !!~~~~~~~~~~~~~~.f90
632 !! b = dens_unit_conversion("g/m^3")
633 !!~~~~~~~~~~~~~~
634 !! b will be \f$ 10^{-6} \f$ as it is the conversion from g/m^3 to g/ccm.
635 !!
636 !! @note New density units can be defined here.
637 !!
638 !! @author Moritz Reichert
639 function dens_unit_conversion(unit)
641  implicit none
642  character(len=*),intent(in) :: unit !< Input unit
643  real(r_kind) :: dens_unit_conversion !< Conversion factor to obtain g/ccm
644 
645  select case (trim(adjustl(unit)))
646  case('')
648  case('-')
650  case('g/cm^3')
652  case('g/m^3')
653  dens_unit_conversion = 1d-6
654  case('kg/cm^3')
656  case('kg/m^3')
657  dens_unit_conversion = 1d-3
658  case default
659  call raise_exception('Problem when analyzing: "'//&
660  trim(adjustl(trajectory_format))//'". '//new_line('A')//'Density unit "'//&
661  trim(adjustl(unit))//'" unknown.',"dens_unit_conversion",&
662  390006)
663  end select
664 end function dens_unit_conversion
665 
666 
667 !>
668 !! Function to convert from a given distance unit to km
669 !!
670 !! ### Example
671 !!~~~~~~~~~~~~~~.f90
672 !! b = dist_unit_conversion("km")
673 !!~~~~~~~~~~~~~~
674 !! b will be \f$ 1 \f$ as it is the conversion from km to km.
675 !!
676 !! @note New distance units can be defined here.
677 !!
678 !! @author Moritz Reichert
679 function dist_unit_conversion(unit)
681  implicit none
682  character(len=*),intent(in) :: unit !< Input unit
683  real(r_kind) :: dist_unit_conversion !< Conversion factor to obtain km
684 
685  select case (trim(adjustl(unit)))
686  case('')
688  case('-')
690  case('km')
692  case('m')
693  dist_unit_conversion = 1e-3
694  case('cm')
695  dist_unit_conversion = 1e-5
696  case default
697  call raise_exception('Problem when analyzing: "'//&
698  trim(adjustl(trajectory_format))//'". '//new_line('A')//'Radius unit "'//&
699  trim(adjustl(unit))//'" unknown.',"dist_unit_conversion",&
700  390007)
701  end select
702 end function dist_unit_conversion
703 
704 
705 
706 !>
707 !! Function to convert from a given neutrino temperature unit to MeV
708 !!
709 !! ### Example
710 !!~~~~~~~~~~~~~~.f90
711 !! b = nutemp_unit_conversion("mev")
712 !!~~~~~~~~~~~~~~
713 !! b will be \f$ 1 \f$ as it is the conversion from Mev to Mev.
714 !!
715 !! @note New (anti-)neutrino temperature units can be defined here.
716 !!
717 !! @author Moritz Reichert
720  implicit none
721  character(len=*),intent(in) :: unit !> Input unit
722  real(r_kind) :: nutemp_unit_conversion !> Conversion factor to obtain MeV
723 
724  select case (trim(adjustl(unit)))
725  case('')
727  case('-')
729  case('mev')
731  case default
732  call raise_exception('Problem when analyzing: "'//&
733  trim(adjustl(trajectory_format))//'". '//new_line('A')//&
734  'Neutrino temperature unit "'//&
735  trim(adjustl(unit))//'" unknown.',"nutemp_unit_conversion",&
736  390008)
737  end select
738 end function nutemp_unit_conversion
739 
740 
741 !>
742 !! Function to convert from a given neutrino energy unit to neutrino temperatures in MeV
743 !!
744 !! ### Example
745 !!~~~~~~~~~~~~~~.f90
746 !! b = nuenergy_unit_conversion("mev")
747 !!~~~~~~~~~~~~~~
748 !! b will be \f$ 3.15^{-1} \f$ as it is the conversion from neutrino energies to
749 !! neutrino temperatures (assuming average energies).
750 !!
751 !! @note New (anti-)neutrino energy units can be defined here.
752 !!
753 !! @author Moritz Reichert
756  implicit none
757  character(len=*),intent(in) :: unit !< Input unit
758  real(r_kind) :: nuenergy_unit_conversion !< Conversion factor to obtain temperatures in MeV
759 
760  select case (trim(adjustl(unit)))
761  case('')
762  nuenergy_unit_conversion = 1.0/3.151374374 ! Energy to temperature
763  case('-')
764  nuenergy_unit_conversion = 1.0/3.151374374
765  case('mev')
766  nuenergy_unit_conversion = 1.0/3.151374374
767  case default
768  call raise_exception('Problem when analyzing: "'//&
769  trim(adjustl(trajectory_format))//'". '//new_line('A')//&
770  'Neutrino energy unit "'//&
771  trim(adjustl(unit))//'" unknown.',"nuenergy_unit_conversion",&
772  390009)
773  end select
774 end function nuenergy_unit_conversion
775 
776 
777 !>
778 !! Function to convert from a given neutrino luminosity unit to erg/s
779 !!
780 !! ### Example
781 !!~~~~~~~~~~~~~~.f90
782 !! b = nulumin_unit_conversion("erg/s")
783 !!~~~~~~~~~~~~~~
784 !! b will be \f$ 1 \f$ as it is the conversion from erg/s to erg/s.
785 !!
786 !! @note New (anti-)neutrino luminosity units can be defined here.
787 !!
788 !! @author Moritz Reichert
791  implicit none
792  character(len=*),intent(in) :: unit !< Input unit
793  real(r_kind) :: nulumin_unit_conversion !< Conversion factor to obtain erg/s
794 
795  select case (trim(adjustl(unit)))
796  case('')
798  case('-')
800  case('erg/s')
802  case default
803  call raise_exception('Problem when analyzing: "'//&
804  trim(adjustl(trajectory_format))//'". '//new_line('A')//&
805  'Neutrino luminosity unit "'//&
806  trim(adjustl(unit))//'" unknown.',"nulumin_unit_conversion",&
807  390010)
808  end select
809 end function nulumin_unit_conversion
810 
811 
812 !>
813 !! Reads the trajectory file.
814 !!
815 !! The columns and structure of the file is determined by the user
816 !! defined parameter \ref parameter_class::trajectory_format.
817 !! The default trajectory format is given by: <b> "time temp dens rad ye" </b>.
818 !! This format will assume a file that looks like:
819 !! \file{
820 !! \#time[s], T9[GK], density[g/cm^3], R[km], Ye
821 !! \#--------------------------------------------
822 !! 0.0000e+00 1.0965e+01 8.7096e+12 4.9273e+01 0.03488
823 !! 2.5000e-05 9.9312e+00 7.4131e+12 5.0361e+01 0.03488
824 !! ...}
825 !! A more complex format, <b> "time:ms x y z log_dens log_temp:K ye" </b>, would assume a file like:
826 !! \file{
827 !! \#t [ms] x[km] y[km] z[km] log(rho[cgs]) log(T[K]) Ye
828 !! \#----------------------------------------------------------------------------------
829 !! 0.0000E+00 0.1051E+02 0.3774E+01 -0.4538E+01 0.1364E+02 0.1016E+02 0.1604E-01
830 !! 0.2521E-01 0.1046E+02 0.4724E+01 -0.4541E+01 0.1363E+02 0.1060E+02 0.1604E-01
831 !! ...}
832 !! Neutrino luminosities and energies are also read here. A format could look like:
833 !! <b> "time temp dens rad ye lnue lanue tnue tanue" </b>. \n
834 !! Possible column names are:
835 !! <pre style="line-height:.3">
836 !! - time : The time (s) of the trajectory
837 !! - temp : The temperature (GK) of the trajectory
838 !! - dens : The density (g/ccm) of the trajectory
839 !! - rad : The radius (km) of the trajectory
840 !! - x,y,z : x, y, and z coordinates (km) of the trajectory
841 !! - ye : The electron fraction
842 !! - lanue : Anti-electron neutrino luminosities (erg/s)
843 !! - lnue : Electron neutrino luminosities (erg/s)
844 !! - tanue : Anti-electron neutrino temperatures (MeV)
845 !! - tnue : Electron neutrino temperatures (MeV)
846 !! - eanue : Anti-electron neutrino energies (MeV)
847 !! - enue : Electron neutrino energies (MeV)
848 !! - lanux : Anti-neutrino luminosities of heavy neutrinos (erg/s)
849 !! - lnux : Neutrino luminosities of heavy neutrinos (erg/s)
850 !! - tanux : Anti-neutrino temperatures of heavy neutrinos (MeV)
851 !! - tnux : Neutrino temperatures of heavy neutrinos (MeV)
852 !! - eanux : Anti-neutrino energies of heavy neutrinos (MeV)
853 !! - enux : Neutrino energies of heavy neutrinos (MeV)
854 !! - skip : skip a column
855 !! .
856 !! </pre>
857 !!
858 !! @note Lines starting with "#" or blank lines are skipped
859 !!
860 !! @author Moritz Reichert
861 !!
862 !! \b Created: 17.12.20
863 subroutine custom_read()
866  use nuflux_class
868  use hydro_trajectory
869  implicit none
870  !
871  integer :: traj_unit, i,j, istat
872  integer :: col_count
873  integer :: time_i,temp_i,dens_i,rad_i,ye_i !< index of the columns
874  integer :: x_i,y_i,z_i !< index for x, y, and z if r not given
875  real(r_kind) :: conv_time,conv_temp,conv_dens !< unit conversion factors
876  real(r_kind) :: conv_rad,conv_ye !< unit conversion factors
877  real(r_kind) :: conv_x,conv_y,conv_z !< unit conversion factors
878  real(r_kind) :: x_tmp,y_tmp,z_tmp !< Temporary storage of x,y, and z to convert them
879  integer :: nuetemp_i,anuetemp_i !< index of the neutrino columns
880  integer :: lnue_i,lanue_i !< index of the neutrino columns
881  real(r_kind) :: conv_tnue,conv_tanue !< unit conversion factors
882  real(r_kind) :: conv_lnue,conv_lanue !< unit conversion factors
883  integer :: nuxtemp_i,anuxtemp_i !< index of the neutrino columns
884  integer :: lnux_i,lanux_i !< index of the neutrino columns
885  real(r_kind) :: conv_tnux,conv_tanux !< unit conversion factors
886  real(r_kind) :: conv_lnux,conv_lanux !< unit conversion factors
887  character(max_fname_len) :: current_col,col_name,col_unit
888  real(r_kind),dimension(:),allocatable :: row_read !< temporary array for one line
889  real(r_kind) :: tny !< tiny value, preventing zeros.
890  logical :: log_switch !< flag to indicate if one columns is logarithmic
891  logical :: ls_time,ls_temp,ls_dens,ls_rad !< which column is it logarithmic?
892  logical :: ls_x,ls_y,ls_z,ls_ye !< which column is it logarithmic?
893  logical :: ls_tnue,ls_tanue,ls_lnue,ls_lanue!< which column is it logarithmic?
894  logical :: ls_tnux,ls_tanux,ls_lnux,ls_lanux!< which column is it logarithmic?
895  integer :: skip_count !< Check how many lines to skip
896  logical :: skipping !< Helper variable
897  character(max_fname_len) :: help_reader !< Helper variable
898 
899  info_entry("custom_read")
900 
901  tny = tiny(tny)
902 
903  ! open the trajectory file
904  traj_unit= open_infile(trajectory_file)
905 
906  ! Convert the custom string to lower case letters
907  do i = 1, max_fname_len
908  j = iachar(trajectory_format(i:i))
909  if (j>= iachar("A") .and. j<=iachar("Z") ) then
910  trajectory_format(i:i) = achar(iachar(trajectory_format(i:i))+32)
911  else
912  continue
913  end if
914  end do
915 
916 
917  ! Count how many lines to skip and how many are there
918  zsteps=0
919  skip_count = 0
920  skipping = .true.
921  do ! determine the number of records
922  read(traj_unit,"(A)",iostat=istat)help_reader
923  ! Go out, file ended
924  if (istat .ne. 0)exit
925  ! Move string to the left
926  help_reader = adjustl(help_reader)
927  ! Check if the line is to skip or not
928  if ((skipping .eqv. .true.) .and. (len_trim(help_reader) .eq. 0)) then
929  skip_count = skip_count+1
930  cycle
931  elseif ((skipping .eqv. .true.) .and. (help_reader(1:1) .eq. "#")) then
932  skip_count = skip_count+1
933  cycle
934  else
935  skipping = .false.
936  end if
937  zsteps= zsteps + 1
938  end do
939 
940  ! allocate arrays
941  allocate(ztime(zsteps), ztemp(zsteps), zdens(zsteps), &
942  zrad(zsteps) , zye(zsteps) , stat=istat)
943  if (istat /= 0) call raise_exception('allocation failed.',"custom_read",390001)
944 
945  ! Allocate neutrino arrays
946  if (((nuflag.ge.1)) .and. (neutrino_mode .eq. 'from_file')) then
947  allocate(tnue(zsteps) ,tnuebar(zsteps) , &
949  tnux(zsteps) ,tnuxbar(zsteps) , &
951  stat=istat)
952  if (istat /= 0) call raise_exception('allocation failed.',"custom_read",390001)
953  end if
954 
955  ! Set default values
956  time_i = 0
957  temp_i = 0
958  dens_i = 0
959  rad_i = 0
960  x_i = 0
961  y_i = 0
962  z_i = 0
963  ye_i = 0
964  ! Same for neutrino quantities (electron neutrinos)
965  nuetemp_i = 0; anuetemp_i = 0
966  lnue_i = 0; lanue_i = 0
967  ! Same for the heavy neutrinos
968  nuxtemp_i = 0; anuxtemp_i = 0
969  lnux_i = 0; lanux_i = 0
970 
971  ! Get correct index from the columns and count them
972  current_col = ''
973  col_count = 0
974  do i = 2,max_fname_len
975  current_col = trim(adjustl(current_col))//trajectory_format(i-1:i-1)
976  if ((trajectory_format(i-1:i-1) .ne. ' ') .and. (trajectory_format(i:i) .eq. ' ')) then
977  ! Count the columns
978  col_count = col_count +1
979  ! Get the name of the column
980  col_name = ''
981  name_loop : do j=1,max_fname_len
982  if ((current_col(j:j) .eq. ':' ) .or. (current_col(j:j) .eq. ' ' )) exit name_loop
983  col_name = trim(adjustl(col_name))//current_col(j:j)
984  end do name_loop
985  ! Get the unit of the column
986  j=j+1
987  col_unit = ''
988  unit_loop : do j=j,max_fname_len
989  if ((current_col(j:j) .eq. ' ' )) exit unit_loop
990  col_unit = trim(adjustl(col_unit))//current_col(j:j)
991  end do unit_loop
992 
993  ! Check if the column is already the logarithm
994  select case (col_name(1:4))
995  case('log_')
996  log_switch = .true.
997  case default
998  log_switch = .false.
999  end select
1000 
1001  ! Remove the "log_" from the string to identify the column
1002  if (log_switch) then
1003  col_name = col_name(5:)
1004  end if
1005 
1006  ! Store the column index and units
1007  select case (trim(adjustl(col_name)))
1008  case('time')
1009  time_i = col_count !index of the column
1010  ls_time=log_switch !check if it should be logarithmic
1011  ! Get the conversion factor to seconds
1012  conv_time = time_unit_conversion(trim(adjustl(col_unit)))
1013  case('temp')
1014  temp_i = col_count !index of the column
1015  ls_temp=log_switch !check if it should be logarithmic
1016  ! Get the conversion factor to GK
1017  conv_temp = temp_unit_conversion(trim(adjustl(col_unit)))
1018  case('dens')
1019  dens_i = col_count !index of the column
1020  ls_dens=log_switch !check if it should be logarithmic
1021  ! Get the conversion factor to g/ccm
1022  conv_dens = dens_unit_conversion(trim(adjustl(col_unit)))
1023  case('rad')
1024  rad_i = col_count !index of the column
1025  ls_rad=log_switch !check if it should be logarithmic
1026  ! Get the conversion factor to km
1027  conv_rad = dist_unit_conversion(trim(adjustl(col_unit)))
1028  case('x')
1029  x_i = col_count !index of the column
1030  ls_x=log_switch !check if it should be logarithmic
1031  ! Get the conversion factor to km
1032  conv_x = dist_unit_conversion(trim(adjustl(col_unit)))
1033  case('y')
1034  y_i = col_count !index of the column
1035  ls_y=log_switch !check if it should be logarithmic
1036  ! Get the conversion factor to km
1037  conv_y = dist_unit_conversion(trim(adjustl(col_unit)))
1038  case('z')
1039  z_i = col_count !index of the column
1040  ls_z=log_switch !check if it should be logarithmic
1041  ! Get the conversion factor to km
1042  conv_z = dist_unit_conversion(trim(adjustl(col_unit)))
1043  case('ye')
1044  ye_i = col_count
1045  ls_ye = log_switch !check if it should be logarithmic, for ye not very probable
1046  ! Ye does not have a unit
1047  conv_ye = 1.0
1048  case('tnue')
1049  nuetemp_i = col_count !index of the column
1050  ls_tnue = log_switch !check if it should be logarithmic
1051  ! Get the conversion factor to MeV
1052  conv_tnue = nutemp_unit_conversion(trim(adjustl(col_unit)))
1053  case('tanue')
1054  anuetemp_i = col_count !index of the column
1055  ls_tanue = log_switch !check if it should be logarithmic
1056  ! Get the conversion factor to MeV
1057  conv_tanue = nutemp_unit_conversion(trim(adjustl(col_unit)))
1058  case('enue')
1059  nuetemp_i = col_count
1060  ls_tnue = log_switch !check if it should be logarithmic
1061  ! Get the conversion factor to MeV and neutrino temperatures
1062  conv_tnue = nuenergy_unit_conversion(trim(adjustl(col_unit)))
1063  case('eanue')
1064  anuetemp_i = col_count
1065  ls_tanue = log_switch !check if it should be logarithmic
1066  ! Get the conversion factor to MeV and neutrino temperatures
1067  conv_tanue = nuenergy_unit_conversion(trim(adjustl(col_unit)))
1068  case('lnue')
1069  lnue_i = col_count
1070  ls_lnue= log_switch !check if it should be logarithmic
1071  ! Get the conversion factor to erg/s
1072  conv_lnue= nulumin_unit_conversion(trim(adjustl(col_unit)))
1073  case('lanue')
1074  lanue_i = col_count
1075  ls_lanue= log_switch !check if it should be logarithmic
1076  ! Get the conversion factor to erg/s
1077  conv_lanue= nulumin_unit_conversion(trim(adjustl(col_unit)))
1078  case("tnux")
1079  nuxtemp_i = col_count !index of the column
1080  ls_tnux = log_switch !check if it should be logarithmic
1081  ! Get the conversion factor to MeV
1082  conv_tnux = nutemp_unit_conversion(trim(adjustl(col_unit)))
1083  case("tanux")
1084  anuxtemp_i = col_count !index of the column
1085  ls_tanux = log_switch !check if it should be logarithmic
1086  ! Get the conversion factor to MeV
1087  conv_tanux = nutemp_unit_conversion(trim(adjustl(col_unit)))
1088  case("enux")
1089  nuxtemp_i = col_count
1090  ls_tnux = log_switch !check if it should be logarithmic
1091  ! Get the conversion factor to MeV and neutrino temperatures
1092  conv_tnux = nuenergy_unit_conversion(trim(adjustl(col_unit)))
1093  case("eanux")
1094  anuxtemp_i = col_count
1095  ls_tanux = log_switch !check if it should be logarithmic
1096  ! Get the conversion factor to MeV and neutrino temperatures
1097  conv_tanux = nuenergy_unit_conversion(trim(adjustl(col_unit)))
1098  case("lnux")
1099  lnux_i = col_count
1100  ls_lnux= log_switch !check if it should be logarithmic
1101  ! Get the conversion factor to erg/s
1102  conv_lnux= nulumin_unit_conversion(trim(adjustl(col_unit)))
1103  case("lanux")
1104  lanux_i = col_count
1105  ls_lanux= log_switch !check if it should be logarithmic
1106  ! Get the conversion factor to erg/s
1107  conv_lanux= nulumin_unit_conversion(trim(adjustl(col_unit)))
1108  case('skip')
1109  continue
1110  case default
1111  call raise_exception('Problem when analyzing: "'//&
1112  trim(adjustl(trajectory_format))//'". '//new_line('A')//&
1113  'Can not read column "'//trim(adjustl(col_name))//'".'//&
1114  new_line('A')//'Column type unknown.',"custom_read",&
1115  390011)
1116  end select
1117  ! Clear the string for the current column
1118  current_col = ''
1119  end if
1120  end do
1121 
1122  ! Check if all necessary hydro-columns were there
1123  if ((time_i .eq. 0) .or. (temp_i .eq. 0) .or. (dens_i .eq. 0)) then
1124  call raise_exception('Problem when analyzing: "'//&
1125  trim(adjustl(trajectory_format))//'". '//new_line('A')//&
1126  'Necessary column is missing.',"custom_read",&
1127  390012)
1128  end if
1129 
1130  ! Ye is only necessary if no seed file is given
1131  if ((ye_i .eq. 0) .and. (.not. read_initial_composition)) then
1132  call raise_exception('Problem when analyzing: "'//&
1133  trim(adjustl(trajectory_format))//'". '//new_line('A')//&
1134  'Ye was missing.',"custom_read",&
1135  390012)
1136  end if
1137 
1138  ! Radius is necessary for neutrinos
1139  if (((rad_i .eq. 0) .and. (x_i .eq. 0)) .and. (nuflag.ge.1) ) then
1140  call raise_exception('Problem when analyzing: "'//&
1141  trim(adjustl(trajectory_format))//'". '//new_line('A')//&
1142  'Radius was missing.',"custom_read",&
1143  390012)
1144  end if
1145 
1146  ! Check if all neutrino-columns were there
1147  if (((nuflag.ge.1)) .and. (neutrino_mode .eq. 'from_file')) then
1148  if ((nuetemp_i .eq. 0) .or. (anuetemp_i .eq. 0) .or. (lnue_i .eq. 0) .or. &
1149  (lanue_i .eq. 0)) then
1150  call raise_exception('Problem when analyzing: "'//&
1151  trim(adjustl(trajectory_format))//'". '//new_line('A')//&
1152  'Necessary column with neutrino information is missing.',"custom_read",&
1153  390013)
1154  end if
1155  end if
1156 
1157  ! Check that the columns for the heavies neutrinos are there in case of neutral
1158  ! current neutrino reactions
1159  if (((nuflag .eq. 4) .or. (nuflag .eq. 5)) .and. (neutrino_mode .eq. 'from_file')) then
1160  if ((nuxtemp_i .eq. 0) .or. (anuxtemp_i .eq. 0) .or. (lnux_i .eq. 0) .or. &
1161  (lanux_i .eq. 0)) then
1162  call raise_exception('Problem when analyzing: "'//&
1163  trim(adjustl(trajectory_format))//'". '//new_line('A')//&
1164  'Necessary column with (heavy) neutrino information is missing.',"custom_read",&
1165  390013)
1166  end if
1167  end if
1168 
1169 
1170  ! read the file
1171  rewind(traj_unit)
1172  ! Skip the first rows again
1173  do i=1,skip_count
1174  read(traj_unit,*)
1175  end do
1176  ! allocate array to read one row
1177  allocate(row_read(col_count),stat=istat)
1178  if (istat /= 0) call raise_exception('Allocation failed.',"custom_read",390001)
1179 
1180  ! Read the trajectory and convert the units
1181  do i=1,zsteps
1182  read(traj_unit,*,iostat=istat)row_read
1183  ! Check that everything is okay
1184  if (istat .ne. 0) then
1185  call raise_exception("Could not read trajectory file."//new_line('A')//&
1186  "Line "//int_to_str(skip_count+i)//" raised a problem.",&
1187  "custom_read",390024)
1188  end if
1189 
1190  ! Time
1191  if (ls_time) ztime(i) = 10**(row_read(time_i))
1192  if (.not. ls_time) ztime(i) = row_read(time_i)
1193  ztime(i) = ztime(i)*conv_time
1194 
1195  ! Density
1196  if (ls_dens) zdens(i) = 10**(row_read(dens_i))
1197  if (.not. ls_dens) zdens(i) = row_read(dens_i)
1198  zdens(i) = zdens(i)*conv_dens
1199 
1200  ! Temperature
1201  if (ls_temp) ztemp(i) = 10**(row_read(temp_i))
1202  if (.not. ls_temp) ztemp(i) = row_read(temp_i)
1203  ztemp(i) = ztemp(i)*conv_temp
1204 
1205  ! Electron fraction
1206  if (ye_i .ne. 0) then
1207  if (ls_ye) zye(i) = 10**(row_read(ye_i))
1208  if (.not. ls_ye) zye(i) = row_read(ye_i)
1209  zye(i) = zye(i)*conv_ye
1210  else
1211  zye(i) = 0.5 ! Fill with dummy value if ye will be taken from a seed file
1212  end if
1213 
1214  ! Radius is special in the case that x, y, or z was given instead of r
1215  if (rad_i .ne. 0) then
1216  if (ls_rad) zrad(i) = 10**(row_read(rad_i))
1217  if (.not. ls_rad) zrad(i) = row_read(rad_i)
1218  zrad(i) = zrad(i)*conv_rad
1219  elseif ((rad_i .eq. 0) .and. (x_i .ne. 0) .and. (y_i .eq. 0) .and. (z_i .eq. 0)) then
1220  if (ls_x) x_tmp = 10**(row_read(x_i))
1221  if (.not. ls_x) x_tmp = row_read(x_i)
1222  zrad(i) = x_tmp*conv_x
1223  elseif ((rad_i .eq. 0) .and. (x_i .ne. 0) .and. (y_i .ne. 0) .and. (z_i .eq. 0)) then
1224  ! check if it was converted by the logarithm
1225  if (ls_x) x_tmp = 10**(row_read(x_i))
1226  if (.not. ls_x) x_tmp = row_read(x_i)
1227  if (ls_y) y_tmp = 10**(row_read(y_i))
1228  if (.not. ls_y) y_tmp = row_read(y_i)
1229  ! Calculate radius
1230  zrad(i) = sqrt((x_tmp*conv_x)**2+(y_tmp*conv_y)**2)
1231  elseif ((rad_i .eq. 0) .and. (x_i .ne. 0) .and. (y_i .ne. 0) .and. (z_i .ne. 0)) then
1232  ! check if it was converted by the logarithm
1233  if (ls_x) x_tmp = 10**(row_read(x_i))
1234  if (.not. ls_x) x_tmp = row_read(x_i)
1235  if (ls_y) y_tmp = 10**(row_read(y_i))
1236  if (.not. ls_y) y_tmp = row_read(y_i)
1237  if (ls_z) z_tmp = 10**(row_read(z_i))
1238  if (.not. ls_z) z_tmp = row_read(z_i)
1239  zrad(i) = sqrt((x_tmp*conv_x)**2+(y_tmp*conv_y)**2+(z_tmp*conv_z)**2)
1240  else
1241  ! The radius is not always necessary. E.g., if there is no extrapolation
1242  ! and no neutrinos.
1243  zrad(i) = 1
1244  ! call raise_exception('Not possible to read the radius, specify r or x!.',"custom_read",&
1245  ! 390014)
1246  end if
1247  ! Read neutrino quantities
1248  if ((nuflag.ge.1) .and. (neutrino_mode .eq. 'from_file')) then
1249 
1250  ! neutrino temperature
1251  if (ls_tnue) tnue(i) = 10**row_read(nuetemp_i)
1252  if (.not. ls_tnue) tnue(i) = row_read(nuetemp_i)
1253  tnue(i) = tnue(i)*conv_tnue
1254 
1255  ! anti-neutrino temperature
1256  if (ls_tanue) tnuebar(i) = 10**row_read(anuetemp_i)
1257  if (.not. ls_tanue) tnuebar(i) = row_read(anuetemp_i)
1258  tnuebar(i) = tnuebar(i)*conv_tanue
1259 
1260  ! neutrino luminosity
1261  if (ls_lnue) nlume(i) = 10**row_read(lnue_i)
1262  if (.not. ls_lnue) nlume(i) = row_read(lnue_i)
1263  nlume(i) = nlume(i)*conv_lnue
1264 
1265  if (ls_lanue) nlumebar(i) = 10**row_read(lanue_i)
1266  if (.not. ls_lanue) nlumebar(i) = row_read(lanue_i)
1267  nlumebar(i) = nlumebar(i)*conv_lanue
1268 
1269  ! Avoid small and negative numbers
1270  if (nlume(i).le.0.d0) nlume(i) = tny
1271  if (nlumebar(i).le.0.d0) nlumebar(i) = tny
1272  if (tnue(i).le.0.d0) tnue(i) = tny
1273  if (tnuebar(i).le.0.d0) tnuebar(i) = tny
1274  end if
1275  ! Do the same for the heavy neutrinos
1276  if ( ((nuflag .eq. 4) .or. (nuflag .eq. 5)) .and. (neutrino_mode .eq. 'from_file')) then
1277  ! Neutrino temperature of heavy neutrinos
1278  if (ls_tnux) tnux(i) = 10**row_read(nuxtemp_i)
1279  if (.not. ls_tnux) tnux(i) = row_read(nuxtemp_i)
1280  tnux(i) = tnux(i)*conv_tnux
1281 
1282  ! Neutrino temperature of heavy anti neutrinos
1283  if (ls_tanux) tnuxbar(i) = 10**row_read(anuxtemp_i)
1284  if (.not. ls_tanux) tnuxbar(i) = row_read(anuxtemp_i)
1285  tnuxbar(i) = tnuxbar(i)*conv_tanux
1286 
1287  ! Neutrino luminosity of heavy neutrinos
1288  if (ls_lnux) nlumx(i) = 10**row_read(lnux_i)
1289  if (.not. ls_lnux) nlumx(i) = row_read(lnux_i)
1290  nlumx(i) = nlumx(i)*conv_lnux
1291 
1292  ! Neutrino luminosity of heavy anti neutrinos
1293  if (ls_lanux) nlumxbar(i) = 10**row_read(lanux_i)
1294  if (.not. ls_lanux) nlumxbar(i) = row_read(lanux_i)
1295  nlumxbar(i) = nlumxbar(i)*conv_lanux
1296 
1297  ! Avoid small and negative numbers
1298  if (nlumx(i).le.0.d0) nlumx(i) = tny
1299  if (tnux(i).le.0.d0) tnux(i) = tny
1300  if (tnuxbar(i).le.0.d0) tnuxbar(i) = tny
1301  if (nlumxbar(i).le.0.d0) nlumxbar(i) = tny
1302  end if
1303  end do
1304 
1305  ! log representation
1306  ztemp = dlog(ztemp)
1307  zdens = dlog(zdens)
1308  zrad = dlog(zrad)
1309 
1310  ! Same for neutrino quantities if necessary
1311  if ((nuflag.ge.1) .and. (neutrino_mode .eq. 'from_file')) then
1312  nlume = dlog(nlume)
1313  nlumebar = dlog(nlumebar)
1314  tnue = dlog(tnue)
1315  tnuebar = dlog(tnuebar)
1316  end if
1317  ! Same for heavy neutrinos if necessary
1318  if ( ((nuflag .eq. 4) .or. (nuflag .eq. 5)) .and. &
1319  (neutrino_mode .eq. 'from_file')) then
1320  nlumx = dlog(nlumx)
1321  nlumxbar = dlog(nlumxbar)
1322  tnux = dlog(tnux)
1323  tnuxbar = dlog(tnuxbar)
1324  end if
1325 
1326  ! close file
1327  call close_io_file(traj_unit,trajectory_file)
1328 
1329  info_exit("custom_read")
1330 
1331 end subroutine custom_read
1332 
1333 
1334 !>
1335 !! Make tests to ensure the trajectory is okay.
1336 !!
1337 !! Otherwise complain. Tests are, for example, the occurence of
1338 !! negative radii at some point or check if the electron fraction
1339 !! is out of bounds (\f$ 0 \le y_e \le 1 \f$).
1340 !!
1341 !! @author Moritz Reichert
1342 subroutine consistency_check()
1343  use hydro_trajectory
1344  implicit none
1345  integer :: i !< Loop variable
1346 
1347  ! Bunch of consistency checks for "from_file" mode
1348  if (trim(trajectory_mode).EQ.'from_file') then
1349 
1350 
1351  ! Negative time
1352  if (ztime(zsteps) .lt. 0) then
1353  call raise_exception("Last point of trajectory had negative time ("//&
1354  trim(adjustl((num_to_str(ztime(zsteps)))))//&
1355  ")!"//new_line('A')//'Please check your input trajectory.',&
1356  "consistency_check",&
1357  390015)
1358  ! Electron fraction out of bounds
1359  elseif ((maxval(zye) .gt. 1) .or. (minval(zye) .lt. 0)) then
1360  call raise_exception("The electron fraction was out of bounds (0 < Ye < 1)! "//&
1361  new_line('A')//'Please check your input trajectory.',&
1362  "consistency_check",&
1363  390016)
1364  end if
1365 
1366 
1367  ! Check negative entries
1368  do i=1, zsteps
1369  ! Negative radius
1370  if (isnan(dexp(zrad(i)))) then
1371  call raise_exception('Problem with input radius: "'//&
1372  'The radius was below zero."'//new_line('A')//&
1373  'Please check your input trajectory.',"consistency_check",&
1374  390017)
1375  ! Negative temperature
1376  elseif (isnan(dexp(ztemp(i)))) then
1377  call raise_exception('Problem with input temperature: "'//&
1378  'The temperature was below zero".'//new_line('A')//&
1379  'Please check your input trajectory.',"consistency_check",&
1380  390018)
1381  ! Negative density
1382  elseif (isnan(dexp(zdens(i)))) then
1383  call raise_exception('Problem with input density: "'//&
1384  'The density was below zero".'//new_line('A')//&
1385  'Please check your input trajectory.',"consistency_check",&
1386  390019)
1387  end if
1388  end do
1389 
1390  ! Check for increasing time
1391  do i=1, zsteps-1
1392  if (ztime(i) .ge. ztime(i+1)) call raise_exception("Time in the trajectory was not monotonically increasing."//&
1393  new_line('A')//"Check your trajectory!","consistency_check",&
1394  390020)
1395  end do
1396  end if
1397 
1398 
1399 end subroutine consistency_check
1400 
1401 
1402 
1403 !>
1404 !! Readini cleanup subroutine
1405 !!
1406 !! At the moment, the subroutine does nothing.
1407 !!
1408 !! @author Moritz Reichert
1409 !!
1410 !! \b Edited:
1411 !! - MR 28.02.2017
1412 !! - OK 18.06.2017
1413 !! .
1414 subroutine readini_finalize()
1416  implicit none
1417  ! not much here really
1418 end subroutine readini_finalize
1419 
1420 
1421 
1422 end module readini
parameter_class::h_track_nuclei_every
integer h_track_nuclei_every
frequency of track nuclei output in hdf5 format
Definition: parameter_class.f90:74
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::track_nuclei_every
integer track_nuclei_every
frequency of track nuclei output
Definition: parameter_class.f90:73
nuflux_class::tnuxbar
real(r_kind), dimension(:), allocatable, public tnuxbar
(anti-)mu and tau neutrino temperatures from trajectory
Definition: nuflux_class.f90:90
readini::consistency_check
subroutine, private consistency_check()
Make tests to ensure the trajectory is okay.
Definition: readini.f90:1343
analysis::snapshot_amount
integer snapshot_amount
Amount of custom snapshots.
Definition: analysis.f90:31
nuflux_class::tnuebar
real(r_kind), dimension(:), allocatable, public tnuebar
(anti-)electron neutrino temperatures from trajectory
Definition: nuflux_class.f90:89
readini::nuenergy_unit_conversion
real(r_kind) function, private nuenergy_unit_conversion(unit)
Function to convert from a given neutrino energy unit to neutrino temperatures in MeV.
Definition: readini.f90:755
analysis::snapshot_time
real, dimension(:), allocatable snapshot_time
point in time for custom snapshot
Definition: analysis.f90:30
nuflux_class::nlumebar
real(r_kind), dimension(:), allocatable, public nlumebar
(anti-)electron neutrino number luminosities from trajectory
Definition: nuflux_class.f90:91
readini::readini_finalize
subroutine, public readini_finalize()
Readini cleanup subroutine.
Definition: readini.f90:1415
error_msg_class
Error handling routines.
Definition: error_msg_class.f90:16
benam_class::benam
integer function, public benam(name)
Returns the index number of isotope 'name'.
Definition: benam_class.f90:251
readini::time_unit_conversion
real(r_kind) function, private time_unit_conversion(unit)
Function to convert from a given time unit to seconds.
Definition: readini.f90:558
readini::temp_unit_conversion
real(r_kind) function, private temp_unit_conversion(unit)
Function to convert from a given temperature unit to GK.
Definition: readini.f90:598
nuflux_class::tnue
real(r_kind), dimension(:), allocatable, public tnue
Definition: nuflux_class.f90:89
readini::dist_unit_conversion
real(r_kind) function, private dist_unit_conversion(unit)
Function to convert from a given distance unit to km.
Definition: readini.f90:680
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
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
readini::read_track_nuclei
subroutine, private read_track_nuclei()
Reads in nuclei that will be tracked and where the abundance will be stored in a separate file.
Definition: readini.f90:181
readini
Subroutines for initialization and parameter parsing.
Definition: readini.f90:15
error_msg_class::str_to_float
real(r_kind) function, public str_to_float(input_string)
Converts a string to a float.
Definition: error_msg_class.f90:179
readini::dens_unit_conversion
real(r_kind) function, private dens_unit_conversion(unit)
Function to convert from a given density unit to g/ccm.
Definition: readini.f90:640
parameter_class::neutrino_mode
character(max_fname_len) neutrino_mode
Similar to trajectory mode.
Definition: parameter_class.f90:185
parameter_class::max_fname_len
integer, parameter, public max_fname_len
maximum length of filenames
Definition: parameter_class.f90:58
parameter_class::trajectory_file
character(max_fname_len) trajectory_file
name of trajectory data file
Definition: parameter_class.f90:152
global_class::track_nuclei_indices
integer, dimension(:), allocatable, public track_nuclei_indices
Variables related to tracking individual nuclei.
Definition: global_class.f90:37
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
parameter_class::trajectory_format
character(max_fname_len) trajectory_format
Format to read the trajectory.
Definition: parameter_class.f90:184
hydro_trajectory::zrad
real(r_kind), dimension(:), allocatable, public zrad
radii from trajectory
Definition: hydro_trajectory.f90:23
parameter_class::read_initial_composition
logical read_initial_composition
specify whether initial distribution of abundances should be read from file
Definition: parameter_class.f90:91
readini::read_seed
subroutine, public read_seed(iniab)
Reads in seed abundances from file parameter_class::seed_file.
Definition: readini.f90:308
readini::readini_init
subroutine, public readini_init()
Initialize the readini module and open files.
Definition: readini.f90:46
parameter_class::seed_file
character(max_fname_len) seed_file
name of file with initial seeds for trajectory run
Definition: parameter_class.f90:153
global_class::net_size
integer, public net_size
total number of isotopes (network size)
Definition: global_class.f90:93
parameter_class::track_nuclei_file
character(max_fname_len) track_nuclei_file
File of nuclei to track. Gives an output similar to mainout.dat.
Definition: parameter_class.f90:181
file_handling_class
Provide some basic file-handling routines.
Definition: file_handling_class.f90:18
error_msg_class::str_to_int
integer function, public str_to_int(input_string)
Converts a string to an integer.
Definition: error_msg_class.f90:155
parameter_class::trajectory_mode
character *20 trajectory_mode
determines how trajectory is calculated (from_file|analytic|expand)
Definition: parameter_class.f90:90
error_msg_class::num_to_str
character(:) function, allocatable, public num_to_str(num)
Converts a given real to a string with format "(1pE10.2)".
Definition: error_msg_class.f90:205
analysis
Contains various routines for analysis and diagnostic output.
Definition: analysis.f90:9
readini::nulumin_unit_conversion
real(r_kind) function, private nulumin_unit_conversion(unit)
Function to convert from a given neutrino luminosity unit to erg/s.
Definition: readini.f90:790
global_class::track_nuclei_nr
integer, public track_nuclei_nr
amount of tracked nuclei
Definition: global_class.f90:38
r_kind
#define r_kind
Definition: macros.h:46
parameter_class::h_custom_snapshots
logical h_custom_snapshots
Same, but in hdf5 format.
Definition: parameter_class.f90:108
parameter_class::seed_format
character(max_fname_len) seed_format
Seed format.
Definition: parameter_class.f90:154
readini::read_custom_snapshots
subroutine, private read_custom_snapshots()
Read in times for snapshots.
Definition: readini.f90:90
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
hydro_trajectory::zdens
real(r_kind), dimension(:), allocatable, public zdens
density information from trajectory
Definition: hydro_trajectory.f90:21
readini::nutemp_unit_conversion
real(r_kind) function, private nutemp_unit_conversion(unit)
Function to convert from a given neutrino temperature unit to MeV.
Definition: readini.f90:719
parameter_class::snapshot_file
character(max_fname_len) snapshot_file
File that contains days, where a snapshot should be made.
Definition: parameter_class.f90:177
file_handling_class::open_infile
integer function, public open_infile(file_name)
Same for reading (input file)
Definition: file_handling_class.f90:126
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
hydro_trajectory::zye
real(r_kind), dimension(:), allocatable, public zye
electron fraction information from trajectory
Definition: hydro_trajectory.f90:22
global_class
Contains types and objects shared between multiple modules.
Definition: global_class.f90:19
file_handling_class::close_io_file
subroutine, public close_io_file(unit_no, file_name)
Close an external file.
Definition: file_handling_class.f90:144
hydro_trajectory::ztemp
real(r_kind), dimension(:), allocatable, public ztemp
temperature information from trajectory
Definition: hydro_trajectory.f90:20
readini::custom_read
subroutine, private custom_read()
Reads the trajectory file.
Definition: readini.f90:864
nuflux_class::nlumx
real(r_kind), dimension(:), allocatable, public nlumx
Definition: nuflux_class.f90:92
parameter_class::custom_snapshots
logical custom_snapshots
If true, a file must be provided with numbers in days. Snapshots will be created for these points in ...
Definition: parameter_class.f90:107
parameter_class::nuflag
integer nuflag
defines type of neutrino reactions used
Definition: parameter_class.f90:85
parameter_class
Contains all runtime parameters as well as phys and math constants.
Definition: parameter_class.f90:24
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