benam_class.f90
Go to the documentation of this file.
1 !> @file benam_class.f90
2 !!
3 !! The error file code for this file is ***W11***.
4 !! @brief Module \ref benam_class for network initialization
5 !! @author Christian Winteler
6 !! @date 12.11.2008
7 !!
8 
9 !> Subroutines needed to initialise the network
10 #include "macros.h"
13  implicit none
14  integer,allocatable,dimension(:,:) :: minmax !< TODO: add description
15 
16  character(len=*), private, parameter :: network_binary_name='network.windat'
17 
18  !
19  ! Public and private fields and methods of the module
20  !
21  public:: &
25 
26  private:: &
29 
30 
31 contains
32 
33 !>
34 !! Reads isotope names from file 'net_source' and saves them in net_names().
35 !! Returns number of isotopes in network.
36 !!
37 !! This function reads the sunet with the same format as the following example:
38 !! \file{
39 !! n
40 !! p
41 !! d
42 !! t
43 !! he3
44 !! he4
45 !! he6
46 !! li6
47 !! li7
48 !! li8
49 !! li9
50 !! ...}
51 !!
52 !! \b Edited:
53 !! - 11.01.14
54 !! .
55 subroutine load_network(net_source)
58 
59  character(*),intent(in) :: net_source !< file where isotopes are specified
60  !
61  integer :: i,sunet,read_stat
62  character(5) :: dummy
63 
64  info_entry("load_network")
65 
66  sunet= open_infile(net_source)
67 
68  i=1
69 
70 !----- read input file to the end to determine number of isotopes in order
71 !----- to allocate net_names(:)
72  do
73  read(sunet,"(2a5)",iostat=read_stat) dummy
74  if (read_stat /= 0) exit
75  i=i+1
76  end do
77  net_size=i-1
78  if (verbose_level.ge.1) then
79  call write_data_to_std_out("Network size",int_to_str(net_size))
80  end if
81 
82  allocate(net_names(net_size))
83  rewind(sunet)
84 
85 !----- read input file again and write isotope names into net_names(:)
86  do i=1,net_size
87  read(sunet,"(2a5)") net_names(i)
88  end do
89 
90  call close_io_file(sunet,net_source)
91 
92  !Setup important indices
93  ihe4 = benam(' he4')
94  ineu = benam(' n')
95  ipro = benam(' p')
96 
97  info_exit("load_network")
98 
99  return
100 
101 end subroutine load_network
102 
103 
104 !>
105 !! @brief Return a string to represent a given reaction
106 !!
107 !! This routine is useful for error messages in case
108 !! a rate is not working as intented.
109 !!
110 !! ### Example
111 !! For rrate(i) being the decay of ni56
112 !! ~~~~~~~~~~~.f90
113 !! a = reaction_string(rrate(i))
114 !! ~~~~~~~~~~~
115 !! will return a="ni56 => co56".
116 !!
117 !! @author Moritz Reichert
118 function reaction_string(reac)
120  implicit none
121  type(reactionrate_type),intent(in) :: reac
122  character(50) :: reaction_string
123  integer :: i
124  logical :: s_prod
125 
126  reaction_string = trim(adjustl(net_names(reac%parts(1))))
127 
128  do i =2, 6
129  s_prod = .false.
130  ! Make a cut between educts and products
131  select case(reac%group)
132  case(1:3,11)
133  if (i .eq. 2) then
134  reaction_string = trim(adjustl(reaction_string))//" =>"
135  s_prod = .true.
136  end if
137  case(4:7)
138  if (i .eq. 3) then
139  reaction_string = trim(adjustl(reaction_string))//" =>"
140  s_prod = .true.
141  end if
142  case(8:9)
143  if (i .eq. 4) then
144  reaction_string = trim(adjustl(reaction_string))//" =>"
145  s_prod = .true.
146  end if
147  case(10)
148  if (i .eq. 5) then
149  reaction_string = trim(adjustl(reaction_string))//" =>"
150  s_prod = .true.
151  end if
152  end select
153 
154  ! Write the names of the isotopes
155  if (reac%parts(i) .ne. 0) then
156  if (.not. s_prod) then
157  reaction_string = trim(adjustl(reaction_string))//" + "//&
158  trim(adjustl(get_net_name(reac%parts(i))))
159  else
160  reaction_string = trim(adjustl(reaction_string))//" "//&
161  trim(adjustl(get_net_name(reac%parts(i))))
162  end if
163  end if
164 
165  end do
166 
167  return
168 end function reaction_string
169 
170 
171 
172 !>
173 !! Returns lowercase of input string. Numbers are not changed.
174 !!
175 !! ### Example:
176 !!~~~~~~~~~~~~.f90
177 !! a = 'Ti44'
178 !! call lowercase(a)
179 !! b = 'This Is A Text 123'
180 !! call lowercase(b)
181 !!~~~~~~~~~~~~
182 !! After this, a will be 'ti44' and b will be 'this is a text 123'
183 !!
184 !! @returns The lowercase of the input string
185 !!
186 subroutine lowercase(str)
187 
188  implicit none
189 
190  character(len=*), intent(inout) :: str !< String to be converted to lower case
191  integer :: i, del
192 
193  del = iachar('a') - iachar('A')
194  do i = 1, len_trim(str)
195  if (lge(str(i:i),'A') .and. lle(str(i:i),'Z')) then
196  str(i:i) = achar(iachar(str(i:i)) + del)
197  end if
198  end do
199 
200  return
201 
202 end subroutine lowercase
203 
204 
205 !>
206 !! Converts isotope names of weak-table format to the ones in reaclib.
207 !!
208 !! ### Example:
209 !!~~~~~~~~~~~~.f90
210 !! a = ' h1'
211 !! call convert(a,b)
212 !! a = ' n01'
213 !! call convert(a,c)
214 !!~~~~~~~~~~~~
215 !! After this, b will be ' p' and c will be ' n'
216 !!
217 !! @returns Reaclib names of neutrons and protons for input "h1" or "n01"
218 !!
219 !! \b Edited:
220 !! - 09.03.2017
221 !! .
222 subroutine convert(wnam,rnam)
223 
224  implicit none
225 
226  character*4,dimension(2) :: wnam !< isotope names in weak-table format
227  character*5,dimension(2),intent(out) :: rnam !< isotope names in reaclib format
228  integer :: i
229 
230  do i=1,2
231  call lowercase(wnam(i))
232  wnam(i)=adjustr(wnam(i))
233  if(wnam(i).eq.' h1')wnam(i)=' p'
234  if(wnam(i).eq.' H1')wnam(i)=' p'
235  if(wnam(i).eq.' n01')wnam(i)=' n'
236  if(wnam(i).eq.' N01')wnam(i)=' n'
237  rnam(i)=' '//wnam(i)
238  end do
239 
240  return
241 
242 end subroutine convert
243 
244 !> Returns the index number of isotope 'name'
245 !!
246 !! \b Edited:
247 !! - 11.01.14
248 !! - 20.05.19
249 !! .
250 function benam(name) result (name_index)
251  use global_class, only: net_names,net_size !< names of isotopes in network
252  implicit none
253  character(len=5),intent(in) :: name !< name of the isotope to be 'indexed'
254  integer :: name_index !< index of the isotope called 'name'
255  integer :: i !< Loop variable
256 
257  ! Naive implementation, loop through all:
258  name_index = 0
259 
260  do i=1,net_size
261  if (trim(adjustl(name)) .eq. trim(adjustl(net_names(i)))) then
262  name_index = i
263  exit
264  end if
265  end do
266 
267  ! Use internal fortran functions
268  ! name_index = findloc(net_names,value=name,dim=1)
269 end function benam
270 
271 
272 !> Getter of net_names, translating indices to a nucleus name
273 !!
274 !! The function will also complain in case the index is out of range
275 !! when the verbose_level is larger than 0.
276 !!
277 !! @author Moritz Reichert
278 !! @date 21.01.21
279 function get_net_name(index,trimmed)
280  use global_class, only: net_names,net_size !< names of isotopes in network
281  implicit none
282  integer,intent(in) :: index !< index of the isotope called 'name'
283  logical,intent(in),optional :: trimmed !< If present, return a name without whitespaces
284  character(:),allocatable :: get_net_name !< name of the isotope
285 
286  ! Check bounds of the function
287  if(index.lt.1 .or. (index.gt.net_size)) then
288  get_net_name = ' '
289  else
290  if (.not. present(trimmed)) get_net_name = net_names(index)
291  if ( present(trimmed)) get_net_name = trim(adjustl(net_names(index)))
292  end if
293 
294 end function get_net_name
295 
296 
297 !>
298 !! Returns the 1/n! factor where n is the number of equal isotopes
299 !! entering a reaction. in addition the amount by which an isotope is
300 !! changed in the reaction is saved (+1 / -1)
301 !!
302 !! \b Edited:
303 !! - 11.01.14
304 !! - 28.07.22, MR: implemented counting factor for all chapters (not only original)
305 !! .
306 subroutine getcoefficients(rate_array,length_rate_array)
308  integer, intent(in) :: length_rate_array !< Length of the rate array
309  type(reactionrate_type),dimension(length_rate_array),intent(inout) :: rate_array !< Input rate array
310  integer :: i, j, k, l, m !< Loop variables
311  real(r_kind) :: dcount !< double count for chapter 10
312 
313 
314  info_entry("getcoefficients")
315 
316  do i=1,length_rate_array
317  rate_array(i)%one_over_n_fac = 1.d0
318 
319  ! added by Marius: for fission reactions the correct coefficients
320  ! are allocated directly in the fission subroutines (neutron multiplicity)
321  if ((rate_array(i)%source.eq.'fiss').or.(rate_array(i)%source.eq.'ms99') &
322  .or.(rate_array(i)%source.eq.'sfis')) cycle
323 
324  rate_array(i)%ch_amount = 0.d0
325  select case (rate_array(i)%group)
326  case(1:3,11)
327 !----- reactions of group 1 to 3 only have one isotope in the initial channel
328  rate_array(i)%ch_amount(1) = -1.d0
329  do j=2,6
330 !----- if rrate(i)%parts(j)=0, there are no more isotopes in the exit channel
331  if (rate_array(i)%parts(j).ne.0) rate_array(i)%ch_amount(j) = 1.d0
332  end do
333  case(4:7)
334 !----- reactions of group 4 to 7 have two isotopes in the initial channel
335  rate_array(i)%ch_amount(1:2) = -1.d0
336  do j=3,6
337  if (rate_array(i)%parts(j).ne.0) rate_array(i)%ch_amount(j) = 1.d0
338  end do
339 !----- if the isotopes in the initial channel are identical, 1/(n)!=1/2
340  if (rate_array(i)%parts(1).eq.rate_array(i)%parts(2)) &
341  rate_array(i)%one_over_n_fac = 1.d0/2.d0
342  case(8:9)
343 !----- reactions of group 8 have 3 isotopes in the initial channel
344  rate_array(i)%ch_amount(1:3) = -1.d0
345  do j=4,6
346  if (rate_array(i)%parts(j).ne.0) rate_array(i)%ch_amount(j) = 1.d0
347  end do
348 !----- if all isotopes in the initial channel are identical, 1/(n)! = 1/6
349  if ((rate_array(i)%parts(1).eq.rate_array(i)%parts(2)) .and. &
350  (rate_array(i)%parts(2).eq.rate_array(i)%parts(3))) then
351  rate_array(i)%one_over_n_fac = 1.d0/6.d0
352 
353 !----- if any two isotopes in the initial channel are identical, 1/(n)! = 1/2
354 !----- since the sequence of isotopes is ordered, 1 and 3 are only identical if
355 !----- all 3 isotopes are identical!
356  else if ((rate_array(i)%parts(1).eq.rate_array(i)%parts(2)) .or. &
357  (rate_array(i)%parts(2).eq.rate_array(i)%parts(3)) .or. &
358  (rate_array(i)%parts(1).eq.rate_array(i)%parts(3))) then
359  rate_array(i)%one_over_n_fac = 1.d0/2.d0
360  end if
361  case(10)
362  !----- reactions of group 8 have 4 isotopes in the initial channel
363  rate_array(i)%ch_amount(1:4) = -1.d0
364  do j=5,6
365  if (rate_array(i)%parts(j).ne.0) rate_array(i)%ch_amount(j) = 1.d0
366  end do
367 
368  ! MR: implemented the following as if statements would become
369  ! quite messy for the case with 4 reactants
370  dcount = 1
371  do j=1,4
372  do k=j+1,4
373  ! Two are equal
374  if (rate_array(i)%parts(k)==rate_array(i)%parts(j)) then
375  dcount = dcount+1
376  end if
377  do m=k+1,4
378  ! Three are equal
379  if ((rate_array(i)%parts(k)==rate_array(i)%parts(j)) .and. &
380  (rate_array(i)%parts(k)==rate_array(i)%parts(m))) then
381  dcount = dcount+2
382  end if
383  do l=m+1,4
384  ! Four are equal
385  if ((rate_array(i)%parts(k)==rate_array(i)%parts(j)) .and. &
386  (rate_array(i)%parts(k)==rate_array(i)%parts(m)) .and. &
387  (rate_array(i)%parts(k)==rate_array(i)%parts(l))) then
388  dcount = dcount+9
389  end if
390  end do
391  end do
392  end do
393  end do
394  ! Set the factor
395  rate_array(i)%one_over_n_fac = 1.d0/dcount
396  case default
397  ! TODO raise exception
398  continue
399  ! call raise_exception
400  end select
401  end do
402 
403  info_exit("getcoefficients")
404 
405 end subroutine getcoefficients
406 
407 
408 
409 !> Read the general network information from a binary file
410 !!
411 !! This subroutine reads the information that is contained in
412 !! the winvn and sunet from a previously saved binary file.
413 !! This is necessary if the parameter \ref use_prepared_network
414 !! is set to .true. and the network is read from a prepared
415 !! network file.
416 !!
417 !! @author M. Reichert
418 !! @date 21.07.23
419 subroutine read_binary_network_data(path)
421  use global_class, only: net_size, t9_data, isotope, &
423  use nucstuff_class, only: ntgp
424  implicit none
425  character(len=*),intent(in) :: path !< Path to the input file
426  integer :: i, alloc_stat
427  integer :: file_id
428 
429  ! Open an unformatted file
430  file_id = open_unformatted_infile(trim(adjustl(path))//trim(adjustl(network_binary_name)))
431 
432  ! Read the network size
433  read(file_id) net_size
434  ! Output something
435  if (verbose_level.ge.1) then
436  call write_data_to_std_out("Network size",int_to_str(net_size))
437  end if
438 
439  ! Allocate and read the net_names
440  allocate(net_names(net_size),stat=alloc_stat)
441  if ( alloc_stat /= 0) call raise_exception('Allocation of "net_names" failed.',&
442  "read_binary_network_data",110001)
443  read(file_id) net_names
444 
445  ! Read the length of partition function grid
446  read(file_id) ntgp
447  ! Allocate grid data array, later set by read_winvn and read_htpf
448  allocate(t9_data(ntgp),stat=alloc_stat)
449  if (alloc_stat .ne. 0) call raise_exception("Could not allocate partition function "//&
450  "temperature grid","read_binary_network_data",&
451  110001)
452 
453  read(file_id) t9_data
454 
455  ! Read indices of neutrons, protons, and alphas
456  read(file_id) ipro
457  read(file_id) ineu
458  read(file_id) ihe4
459 
460  ! Allocate the isotope array
461  allocate(isotope(net_size),stat=alloc_stat)
462  if ( alloc_stat /= 0) call raise_exception('Allocation of "isotope" failed.',&
463  "read_binary_network_data",110001)
464 
465  ! Allocate the grid for the partition functions in the correct size
466  do i=1,net_size
467  allocate(isotope(i)%part_func(ntgp),stat=alloc_stat)
468  if (alloc_stat .ne. 0) call raise_exception("Could not allocate grid for partition functions."&
469  ,"read_binary_network_data",&
470  110001)
471  end do
472 
473  ! Read the isotope data
474  do i=1,net_size
475  read(file_id) isotope(i)%name
476  read(file_id) isotope(i)%mass
477  read(file_id) isotope(i)%p_nr
478  read(file_id) isotope(i)%n_nr
479  read(file_id) isotope(i)%spin
480  read(file_id) isotope(i)%mass_exc
481  read(file_id) isotope(i)%part_func
482  end do
483 
484  close(file_id)
485 
486 end subroutine read_binary_network_data
487 
488 
489 !> Save the general network information to a binary file
490 !!
491 !! This subroutine saves the information that is contained in
492 !! the winvn and sunet. This is necessary if the code is
493 !! run in network preparation mode for the parameter
494 !! \ref use_prepared_network .
495 !!
496 !! @author M. Reichert
497 !! @date 21.07.23
500  use global_class, only: net_size, t9_data, isotope, &
502  use nucstuff_class, only: ntgp
503  implicit none
504  character(len=*),intent(in) :: path !< Path to the output file
505  integer :: i
506  integer :: file_id
507 
508  info_entry("output_binary_network_data")
509 
510  ! Open an unformatted file
511  file_id = open_unformatted_outfile(trim(adjustl(path))//trim(adjustl(network_binary_name)))
512 
513  ! Write the network size
514  write(file_id) net_size
515  ! Write the network names
516  write(file_id) net_names
517  ! Write the length of partition function grid
518  write(file_id) ntgp
519  ! Write t9 grid data for partition functions
520  write(file_id) t9_data
521 
522  ! Write indices of neutrons, protons, and alphas
523  write(file_id) ipro
524  write(file_id) ineu
525  write(file_id) ihe4
526 
527  ! Write the isotope data
528  do i=1,net_size
529  write(file_id) isotope(i)%name
530  write(file_id) isotope(i)%mass
531  write(file_id) isotope(i)%p_nr
532  write(file_id) isotope(i)%n_nr
533  write(file_id) isotope(i)%spin
534  write(file_id) isotope(i)%mass_exc
535  write(file_id) isotope(i)%part_func
536  end do
537 
538  close(file_id)
539 
540  info_exit("output_binary_network_data")
541 
542 end subroutine output_binary_network_data
543 
544 
545 
546 !>
547 !! Reads nuclear properties (name,a,n,z,spin,mass excess,partition functions)
548 !! from file 'winvn' and htpf file and writes them into isotope(:).
549 !! Also the arrays of the partition function grid and temperature grid are
550 !! initialized here.
551 !!
552 !! \b Edited:
553 !! - 11.01.14
554 !! - 11.02.21 - MR: Implemented a switch for htpf functions and
555 !! moved things to additional subroutine
556 !! .
560  net_source
561  use nucstuff_class, only: ntgp, is_stable
562  use global_class, only: net_size, isotope, t9_data
564  implicit none
565  integer :: winvn, htpf !< File IDs
566  integer :: alloc_stat !< Allocation status variable
567  integer :: i !< Loop variable
568 
569  info_entry("get_nuclear_properties")
570 
571  ! Load the network
573  allocate(isotope(net_size),stat=alloc_stat)
574  if ( alloc_stat /= 0) call raise_exception('Allocation of "isotope" failed.',&
575  "get_nuclear_properties",110001)
576 
577  ! Set the number of temperature grid points
578  ! where the partition functions are tabulated.
579  ! In case high temperature partition functions are included
580  ! more grid points are used.
581  if (.not. use_htpf) then
582  ntgp = 24
583  else
584  ntgp = 72
585  end if
586 
587  ! Allocate grid data array, later set by read_winvn and read_htpf
588  allocate(t9_data(ntgp),stat=alloc_stat)
589  if (alloc_stat .ne. 0) call raise_exception("Could not allocate partition function "//&
590  "temperature grid","get_nuclear_properties",&
591  110001)
592 
593  ! Allocate the grid for the partition functions in the correct size
594  do i=1,net_size
595  allocate(isotope(i)%part_func(ntgp),stat=alloc_stat)
596  if (alloc_stat .ne. 0) call raise_exception("Could not allocate grid for partition functions."&
597  ,"get_nuclear_properties",&
598  110001)
599  end do
600 
601  ! Always read winvn
602  winvn= open_infile(isotopes_file)
603  call read_winvn(winvn)
604  call close_io_file(winvn,isotopes_file)
605 
606  ! In case high temperature partition functions are included
607  if (use_htpf) then
608  htpf = open_infile(htpf_file)
609  call read_htpf(htpf)
610  call close_io_file(htpf,htpf_file)
611  end if
612 
613  ! Check if the isotope is stable
614  do i=1,net_size
615  isotope(i)%is_stable = is_stable(isotope(i)%p_nr,isotope(i)%n_nr)
616  end do
617 
618  ! Read nuloss file
619  if (use_neutrino_loss_file) then
621  end if
622 
623 
624  info_exit("get_nuclear_properties")
625 
626  end subroutine read_ascii_network_data
627 
628 
629 
630 !>
631 !! Reads nuclear properties (name,a,n,z,spin,mass excess,partition functions)
632 !! from file 'winvn' and htpf file and writes them into isotope(:).
633 !! Also the arrays of the partition function grid and temperature grid are
634 !! initialized here.
635 !!
636 !! \b Edited:
637 !! - 11.01.14
638 !! - 11.02.21 - MR: Implemented a switch for htpf functions and
639 !! moved things to additional subroutine
640 !! .
644  implicit none
645 
646  info_entry("get_nuclear_properties")
647 
648  if (use_prepared_network) then
650  else
652  end if
653 
654  info_exit("get_nuclear_properties")
655 
656 end subroutine get_nuclear_properties
657 
658 
659 
660 !>
661 !! Reads nuclear properties (name,a,n,z,spin,mass excess,partition functions)
662 !! from file 'winvn' and writes them into isotope(:).
663 !! An example entry of a winvn can look like:
664 !! \l_file{
665 !! ne33 33.000 10 23 1.5 45.997 reac1
666 !! 1.00000E+0 1.00000E+0 1.00000E+0 1.00000E+0 1.00000E+0 1.00000E+0 1.00000E+0 1.00000E+0
667 !! 1.00000E+0 1.00000E+0 1.00000E+0 1.00000E+0 1.00000E+0 1.00000E+0 1.00000E+0 1.01000E+0
668 !! 1.01000E+0 1.02000E+0 1.03000E+0 1.07000E+0 1.12000E+0 1.19000E+0 1.28000E+0 1.40000E+0
669 !! ...}
670 !!
671 !! \b Edited:
672 !! - 11.02.21 - MR: Moved it from get_nuclear_properties to this subroutine
673 !! .
674 subroutine read_winvn(winvn)
675  use format_class
676  use global_class, only: isotope, t9_data
677  implicit none
678  integer,intent(in) :: winvn !< File ID of the winvn
679  integer :: i, j , read_stat
680  character(5) :: name, tempname
681  character(5),dimension(:),allocatable :: data_names
682  integer :: data_cnt
683  real(r_kind) :: za
684  integer :: zp !< Proton number
685  integer :: zn !< Neutron number
686  real(r_kind) :: sp !< Spin of the ground state
687  real(r_kind) :: bi !< binding energy
688  real(r_kind), dimension(24) :: pf !< Partition function grid
689 
690  info_entry("read_winvn")
691  i = 1
692 
693  read (winvn,*)
694  read (winvn,"(23f3.2,f3.1)") (t9_data(j),j=1,24)
695 !----- skip part of winvn where all isotopes are listed. the last isotope in
696 !----- this list appears twice.
697  read (winvn,"(a5)") name !read isotope name
698  do
699  read (winvn,"(a5)",iostat = read_stat) tempname !read next isotope name
700  if (read_stat /= 0) call raise_exception("Problem reading winvn file. Check the winvn.",&
701  "get_nuclear_properties",&
702  110003)
703 
704 
705 !----- if last two isotope names are identical, end of list reached
706  if (tempname == name) exit
707  name = tempname
708  i = i+1
709  end do
710  data_cnt = i
711 
712  allocate(data_names(data_cnt))
713 
714  rewind(winvn)
715  read(winvn,'(/)')
716  do i=1,data_cnt
717  read(winvn,"(a5)") data_names(i)
718  end do
719  read(winvn,*)
720 ! data_names = adjustr(data_names)
721  call sunet_check (data_names)
722  deallocate (data_names)
723 !----- reading of nuclear properties starts here:
724  i=0
725  do
726  read (winvn,my_format(4),iostat = read_stat)name,za,zp,zn,sp,bi
727  if (read_stat /= 0) exit
728 ! read (winvn,my_format(5)) (pf(j),j=1,24)
729  read (winvn,*) (pf(j),j=1,24)
730  ! Normal cases, i.e., not Al26
731  i = benam(name)
732  if (i == 0) cycle
733  isotope(i)%name = name
734  isotope(i)%mass = zp+zn
735  isotope(i)%p_nr = zp
736  isotope(i)%n_nr = zn
737  isotope(i)%spin = sp
738  isotope(i)%mass_exc = bi
739  isotope(i)%part_func(1:24) = pf
740 
741  end do
742 
743 
744  info_exit("read_winvn")
745 
746 end subroutine read_winvn
747 
748 
749 
750 !>
751 !! Checks if sunet file contains valid isotope names
752 !!
753 !! \b Edited:
754 !! - 11.01.14
755 !! .
756 subroutine sunet_check(ref_array)
757  use global_class, only:net_names
758 
759  character(5),dimension(:),intent(in) :: ref_array !< array of isotope names
760  integer,dimension(:),allocatable :: chk !< Check variable, 1: included, 0: not included
761  integer :: ref_len, net_len
762  integer :: i,j !< Loop variale
763  character(500) :: e_message !< Error message
764  character(5) :: net_name_tmp !< Temporary helper variable
765 
766  info_entry("sunet_check")
767 
768  ref_len = size(ref_array)
769  net_len = size(net_names)
770 
771  allocate(chk(net_len))
772  chk=0
773 
774  do i=1,net_len
775 
776  net_name_tmp = net_names(i)
777 
778  in:do j=1,ref_len
779  if(trim(adjustl(net_name_tmp)).eq.trim(adjustl(ref_array(j))))then
780  chk(i)=1
781  exit in
782  end if
783  end do in
784  end do
785 
786  if(any(chk.eq.0)) then
787  e_message = ""
788  do i=1,net_len
789  if(chk(i).eq.0) e_message = trim(adjustl(e_message))//net_names(i)//&
790  " not in isotopes database (winvn)."//new_line("A")
791  end do
792  call raise_exception(trim(adjustl(e_message))//"Problem reading sunet file. Check the sunet.",&
793  "sunet_check",&
794  110004)
795  end if
796 
797  info_exit("sunet_check")
798  return
799 
800 end subroutine sunet_check
801 
802 
803 !>
804 !! Read the file with high-temperature partition function
805 !! (normally datafile2.dat). An example of the file may look like:
806 !!
807 !! \l_file{
808 !! Title: Nuclear Partition Functions at Temperatures Exceeding 10^10^ K
809 !! Author: Rauscher T.
810 !! Table: Renormalized partition functions G(T_9_) including high temperature
811 !! corrections. The values given here were calculated with level densities
812 !! based on FRDM input (see text).
813 !! \================================================================================
814 !! Byte-by-byte Description of file: datafile2.txt
815 !! \--------------------------------------------------------------------------------
816 !! Bytes Format Units Label Explanations
817 !! \--------------------------------------------------------------------------------
818 !! 1- 5 A5 --- Name Nuclide name
819 !! 7- 8 I2 --- Z Charge number of nuclide
820 !! 10- 12 I3 --- A Mass number of nuclide
821 !! 15- 17 F3.1 --- J0 Ground-state spin of nuclide
822 !! 19- 27 E9.2 --- G12 Renormalized partition function for T = 12E9
823 !! ....
824 !! o13 8 13 1.5 1.00E+000 1.00E+000 9.99E-001 9.95E-001 9.90E-001 9.84E-001 9.76E-001 9.68E-001 9.59E-001 ...
825 !! ...}
826 !!
827 !! \b Edited: 11.01.14
828 subroutine read_htpf(source)
829  use global_class, only: t9_data, isotope
830 
831  integer,intent(in) :: source !< HTPF file name
832  !
833  integer :: n, i
834  character*5 :: namtmp
835  character*69 :: dummy
836  real*8,dimension(48) :: pftmp
837  integer :: stat
838  integer,dimension(:),allocatable :: check
839 
840  info_entry("read_htpf")
841 
842  n = size(isotope)
843  allocate(check(n))
844 
845  check = 0
846 
847  read(source,'(13/)')
848  do i=25,72
849  read(source,'(a69,es5.0)')dummy,t9_data(i)
850  end do
851 
852  read(source,*)
853  out:do
854  read(source,'(a5,t19,48es10.2)',iostat=stat)namtmp,pftmp
855  if(stat.ne.0) exit out
856  namtmp = adjustr(namtmp)
857  in:do i=1,n
858  if(namtmp.eq.isotope(i)%name) then
859  isotope(i)%part_func(25:72) = pftmp(1:48)
860  check(i) = 1
861  cycle out
862  end if
863  end do in
864  end do out
865 
866  do i = 1,n
867  if(check(i).ne.1) then
868  isotope(i)%part_func(25:72) = isotope(i)%part_func(24)
869  end if
870  end do
871  deallocate(check)
872 
873  info_exit("read_htpf")
874 
875  return
876 
877 end subroutine read_htpf
878 
879 
880 !>
881 !! Finds an isotope index in the network table, given its A and Z.
882 !! In case it was not found, -1 is returned.
883 !!
884 !!
885 !! \b Edited: 11.01.14
886 function findaz(ai,zi) result (azind)
887  use global_class, only:isotope,net_size
888 
889  integer,intent(in) :: ai !< A
890  integer,intent(in) :: zi !< Z
891  integer :: azind !< return index
892  integer :: i
893 
894  azind = 0
895  do i=1,net_size
896  if ((isotope(i)%p_nr.eq.zi) .and. (isotope(i)%mass.eq.ai)) then
897  azind = i
898  exit
899  end if
900  end do
901 
902  if (azind.eq.0) then
903  azind = -1
904  end if
905 
906  return
907 
908 end function findaz
909 
910 !>
911 !! Returns Amin and Amax for each isotopic chain in minmax
912 !!
913 !! \b Edited: 11.01.14
914 !! .
915 subroutine get_minmax()
916  use global_class, only: isotope, net_size
917  !
918  integer :: i
919  integer :: ind
920  integer :: max_p
921 
922  info_entry("get_minmax")
923 
924  !Find maximum proton number
925  max_p= 0
926  do i= 1,net_size
927  if (isotope(i)%p_nr .gt. max_p) max_p = isotope(i)%p_nr
928  end do
929 
930 
931  allocate(minmax(max_p,2))
932 
933  minmax = 0
934 
935  do i = 1,net_size
936  if (isotope(i)%p_nr.eq.0) cycle
937  ind = isotope(i)%p_nr
938 
939  if (minmax(ind,1).eq.0) then
940  minmax(ind,1) = isotope(i)%mass
941  minmax(ind,2) = isotope(i)%mass
942  else if (isotope(i)%mass.gt.minmax(ind,2)) then
943  minmax(ind,2) = isotope(i)%mass
944  else if (isotope(i)%mass.lt.minmax(ind,1)) then
945  minmax(ind,1) = isotope(i)%mass
946  end if
947  end do
948 
949  info_exit("get_minmax")
950 
951  return
952 
953 end subroutine get_minmax
954 
955 
956 !> Read a file with neutrino loss energy.
957 !!
958 !! This file contains the neutrino loss energy for the beta decays in the network.
959 !! The information is used in case nuclear heating is turned on.
960 !! An example of the file could look like this:
961 !! \file{...
962 !! al34 4.803857E+00
963 !! al35 6.072946E+00
964 !! al37 5.639200E+00
965 !! si25 4.794861E+00
966 !! si26 1.968612E+00
967 !! si27 2.070827E+00
968 !! si31 8.963707E-01
969 !! si32 1.581000E-01
970 !! si34 1.778200E+00
971 !! si35 3.314272E+00
972 !! si36 3.432230E+00
973 !! si38 3.446900E+00
974 !!... }
975 !! The first column is the isotope name, the second column is the average neutrino loss
976 !! energy in MeV.
977 !!
978 !! @author Moritz Reichert
979 !! @date 31.03.2023
980 subroutine read_neutrino_loss(filename)
983  implicit none
984  character(len=*), intent(in) :: filename !< Name of the file to read
985  !-- Internal Variables
986  real(r_kind) :: qnuloss_tmp !< Temporary variable for reading
987  character(len=5) :: name !< Isotope name
988  integer :: i !< Loop counter
989  integer :: stat !< Status of the file read and allocation
990  integer :: file_id !< File ID
991 
992  info_entry("read_neutrino_loss")
993 
994  ! Allocate the array
995  allocate(qnuloss(net_size), stat=stat)
996 
997  ! Allocation status, complain if something is wrong
998  if (stat .ne. 0) then
999  call raise_exception("Could not allocate Qnuloss array", &
1000  "read_neutrino_loss",110001)
1001  end if
1002  ! Set to empty values
1003  qnuloss(:) = -1
1004 
1005  ! Open and read the file
1006  file_id = open_infile(filename)
1007  do
1008  read(file_id,*,iostat=stat) name, qnuloss_tmp
1009  if (stat .ne. 0) exit
1010  do i = 1, net_size
1011  if (trim(adjustl(name)) .eq. trim(adjustl(isotope(i)%name))) then
1012  qnuloss(i) = qnuloss_tmp
1013  exit
1014  end if
1015  end do
1016  end do
1017 
1018  ! Close the file again
1019  close(file_id)
1020 
1021  info_exit("read_neutrino_loss")
1022 
1023 end subroutine read_neutrino_loss
1024 
1025 
1026 !>
1027 !! Identifies the nuclide names and indices corresponding to z,n combinations
1028 !! (z1,n1), (z2,n2).
1029 !!
1030 !! If any of the two nuclides is not part of the network,
1031 !! err=1 and all other properties are set to 0 or " " respectively.
1032 !!
1033 !!
1034 !! \b Edited:
1035 !! - 12.01.14
1036 !! - 23.01.21, MR - moved it to benam_class
1037 !! .
1038 subroutine ident(z1,n1,z2,n2,nam1,nam2,ind1,ind2,err)
1039  use global_class
1040 
1041  implicit none
1042 
1043 !----- subroutine arguments
1044  integer :: z1,z2,n1,n2 !< proton and neutron numbers
1045  character(5), intent(out) :: nam1,nam2 !< nuclide names as they appear in sunet
1046  integer, intent(out) :: ind1,ind2 !< nuclide index in the network
1047  integer, intent(out) :: err !< 0 if nuclides are identified successfully
1048  !! 1 if any of the two (z,n) combinations
1049  !! could not be assigned to a nuclide
1050  !! in the network
1051 
1052 !----- runtime variables
1053  integer :: i,j,ini
1054 !----- dummy variables
1055  integer :: zt,nt,indt ! temporary values
1056  character(5) :: namt
1057  integer :: inv
1058 
1059  err = 0
1060  ind1 = 0
1061  ind2 = 0
1062  nam1 = " "
1063  nam2 = " "
1064  if (z2.lt.z1) then
1065  zt = z2
1066  nt = n2
1067  z2 = z1
1068  n2 = n1
1069  z1 = zt
1070  n1 = nt
1071  inv = 1
1072  else
1073  zt=z1
1074  nt=n1
1075  inv = 0
1076  end if
1077  out: do j=1,2
1078  in: do i=zt,net_size
1079  if((i.gt.3).and.(isotope(i)%p_nr.gt.zt)) exit out
1080  if((isotope(i)%p_nr.eq.zt).and.(isotope(i)%n_nr.eq.nt)) then
1081  select case(j)
1082  case(1)
1083  ind1 = i
1084  nam1 = isotope(i)%name
1085  case(2)
1086  ind2 = i
1087  nam2 = isotope(i)%name
1088  end select
1089  exit in
1090  end if
1091  end do in
1092  zt = z2
1093  nt = n2
1094  ini = ind1
1095  end do out
1096 
1097  if (ind2.ne.0) then
1098  if (inv .eq. 1) then
1099  namt = nam1
1100  indt = ind1
1101  nam1 = nam2
1102  ind1 = ind2
1103  nam2 = namt
1104  ind2 = indt
1105  return
1106  else
1107  return
1108  end if
1109  else
1110  ind1 = 0
1111  nam1 = " "
1112  err = 1
1113  return
1114  end if
1115 
1116 end subroutine ident
1117 
1118 
1119 
1120 !===============================================================================
1121 
1122 end module benam_class
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
benam_class::read_ascii_network_data
subroutine, private read_ascii_network_data()
Reads nuclear properties (name,a,n,z,spin,mass excess,partition functions) from file 'winvn' and htpf...
Definition: benam_class.f90:558
global_class::ipro
integer, public ipro
index of alphas, neutrons and protons
Definition: global_class.f90:94
global_class::reactionrate_type
reaction rate type
Definition: global_class.f90:44
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
benam_class::read_htpf
subroutine, private read_htpf(source)
Read the file with high-temperature partition function (normally datafile2.dat). An example of the fi...
Definition: benam_class.f90:829
global_class::t9_data
real(r_kind), dimension(:), allocatable, public t9_data
temperatures at which partition functions are given [GK]
Definition: global_class.f90:97
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
benam_class::reaction_string
character(50) function, public reaction_string(reac)
Return a string to represent a given reaction.
Definition: benam_class.f90:119
parameter_class::use_neutrino_loss_file
logical use_neutrino_loss_file
Use a file with Qnu values?
Definition: parameter_class.f90:105
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
benam_class::read_winvn
subroutine, private read_winvn(winvn)
Reads nuclear properties (name,a,n,z,spin,mass excess,partition functions) from file 'winvn' and writ...
Definition: benam_class.f90:675
nucstuff_class::ntgp
integer, public ntgp
(24/72) Number of temp grid points for the partition functions
Definition: nucstuff_class.f90:17
benam_class::read_binary_network_data
subroutine, private read_binary_network_data(path)
Read the general network information from a binary file.
Definition: benam_class.f90:420
global_class::ineu
integer, public ineu
Definition: global_class.f90:94
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
benam_class::output_binary_network_data
subroutine, public output_binary_network_data(path)
Save the general network information to a binary file.
Definition: benam_class.f90:499
format_class::my_format
character(60), dimension(100) my_format
Definition: format_class.f90:19
nucstuff_class
Module with helper functions such as rate tabulation, partition functions, and theoretical weak rates...
Definition: nucstuff_class.f90:11
parameter_class::use_htpf
logical use_htpf
Use high temperature partition functions or not.
Definition: parameter_class.f90:145
benam_class::minmax
integer, dimension(:,:), allocatable minmax
TODO: add description.
Definition: benam_class.f90:14
parameter_class::isotopes_file
character(max_fname_len) isotopes_file
properties of all isotopes in the network: masses, partition functions etc. (winvn)
Definition: parameter_class.f90:156
benam_class::network_binary_name
character(len= *), parameter, private network_binary_name
Definition: benam_class.f90:16
global_class::qnuloss
real(r_kind), dimension(:), allocatable, public qnuloss
Qnu for decay of each isotope [MeV].
Definition: global_class.f90:96
parameter_class::htpf_file
character(max_fname_len) htpf_file
high-temperature partition functions (htpf.dat)
Definition: parameter_class.f90:157
global_class::net_size
integer, public net_size
total number of isotopes (network size)
Definition: global_class.f90:93
file_handling_class
Provide some basic file-handling routines.
Definition: file_handling_class.f90:18
nucstuff_class::is_stable
logical function, public is_stable(Z, N)
Function to decide whether a given isotope is stable or not.
Definition: nucstuff_class.f90:65
benam_class::load_network
subroutine, private load_network(net_source)
Reads isotope names from file 'net_source' and saves them in net_names(). Returns number of isotopes ...
Definition: benam_class.f90:56
benam_class::lowercase
subroutine lowercase(str)
Returns lowercase of input string. Numbers are not changed.
Definition: benam_class.f90:187
r_kind
#define r_kind
Definition: macros.h:46
benam_class::get_nuclear_properties
subroutine, public get_nuclear_properties()
Reads nuclear properties (name,a,n,z,spin,mass excess,partition functions) from file 'winvn' and htpf...
Definition: benam_class.f90:642
benam_class::get_minmax
subroutine, public get_minmax()
Returns Amin and Amax for each isotopic chain in minmax.
Definition: benam_class.f90:916
parameter_class::neutrino_loss_file
character(max_fname_len) neutrino_loss_file
Path to a file containing Qnu values.
Definition: parameter_class.f90:106
file_handling_class::open_infile
integer function, public open_infile(file_name)
Same for reading (input file)
Definition: file_handling_class.f90:126
benam_class::convert
subroutine, public convert(wnam, rnam)
Converts isotope names of weak-table format to the ones in reaclib.
Definition: benam_class.f90:223
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
parameter_class::net_source
character(max_fname_len) net_source
list of isotopes included in the network (sunet)
Definition: parameter_class.f90:155
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
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
format_class
Define custom format statements used to read in major data files.
Definition: format_class.f90:16
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
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
benam_class::sunet_check
subroutine, private sunet_check(ref_array)
Checks if sunet file contains valid isotope names.
Definition: benam_class.f90:757
parameter_class::prepared_network_path
character(max_fname_len) prepared_network_path
Prepared network folder.
Definition: parameter_class.f90:198
parameter_class
Contains all runtime parameters as well as phys and math constants.
Definition: parameter_class.f90:24
benam_class::read_neutrino_loss
subroutine, private read_neutrino_loss(filename)
Read a file with neutrino loss energy.
Definition: benam_class.f90:981
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
benam_class
Subroutines needed to initialise the network.
Definition: benam_class.f90:11