fission_rate_module.f90
Go to the documentation of this file.
1 !> @file fission_rate_module.f90
2 !!
3 !! The error file code for this file is ***W19***.
4 !! Contains the module \ref fission_rate_module
5 
6 !> Module to deal with fission reactions
7 !!
8 !! This module contains subroutines to read fission reactions
9 !! and fission fragment distributions. Furthermore, it counts the
10 !! amount of reactions. Many subroutines here were originally implemented
11 !! by M. Eichler and C. Winteler.
12 !!
13 !! @remark All subroutines have often been existed at other places in
14 !! the network and possibly as parts of other subroutines.
15 #include "macros.h"
17  implicit none
18 
19 
20  !> fission rate type, designed to save fragment distribution at initialization
21  type,public :: fissionrate_type
22  integer :: fissnuc_index !< index of parent nucleus
23  integer :: channels !< number of fragment pairs for each fission rate
24  integer :: mode !< fission mode; 1:n-induced fission 2: spontaneous and beta-delayed fission
25  integer :: released_n !< Amount of released neutrons for beta-delayed fission
26  integer :: dimens !< dimension of fissparts array
27  real(r_kind) :: cached !< computed rate
28  real(r_kind) :: averageq !< average Q value, weighted over all fragment channels
29  character(4) :: src !< Source of the reaction
30  integer :: reac_type !< "rrt_sf": spontaneous fission, "rrt_bf": beta-delayed fission, "rrt_nf": neutron-induced fission
31  integer,dimension(:),allocatable :: fissparts !< corresponds to rrate()%parts() array
32  integer,dimension(:,:),allocatable :: cscf_ind !< cscf_ind (i,j) gives the position of the entry \f$\frac{d\dot{Y}_{j}}{dY_{i}}\f$ in the cscf data array
33  real(r_kind),dimension(9) :: param !< rate parameters a0-a9, as given in reaclib file
34  real(r_kind),dimension(:),allocatable :: q_value !< Q value of each fission channel
35  real(r_kind),dimension(:),allocatable :: channelprob !< probability for each fragment pair
36  real(r_kind),dimension(:),allocatable :: ch_amount !< corresponds to rrate(i)%ch_amount(j); for fragment i ch_amount(i) = +1 * channelprob(i)
37  end type fissionrate_type
38 
39  type(fissionrate_type),dimension(:),allocatable,public :: fissrate !< Array storing fission reactions
40 
41  real(r_kind),dimension(:,:),allocatable,private :: beta_delayed_fiss_probs
42  integer,private :: amount_cols !< Amount of columns in the beta-delayed fission file
43 
44 
45  character(len=*), private, parameter :: fiss_binary_name='fiss_rates.windat' !< Name of the binary file containing the fission rates
46 
47 
48  type,private :: fragtype
49  integer :: zp !< Z of fissioning nucleus
50  integer :: ap !< A of fissioning nucleus
51  integer :: neutrons !< number of neutrons emitted
52  integer :: nr_frags !< Number of fragments
53  real(r_kind) :: yn !< Yield for neutrons
54  integer,dimension(:),allocatable :: net_idx !< index of fragment in network
55  integer,dimension(:),allocatable :: z !< Z of fragment
56  integer,dimension(:),allocatable :: a !< A of fragment
57  real(r_kind),dimension(:),allocatable :: y !< Yields of fragment
58  end type fragtype
59  type(fragtype),dimension(:),allocatable,private :: fissfrags_n_induced !< Array storing fragment distributions of neutron-induced fission from file
60  type(fragtype),dimension(:),allocatable,private :: fissfrags_spontaneous !< Array storing fragment distributions of spontaneous fission from file
61  type(fragtype),dimension(:),allocatable,private :: fissfrags_beta_delayed !< Array storing fragment distributions of beta-delayed fission from file
62 
63 
64 
65 
66  integer, public, parameter :: fiss_neglect=5 !< Amount of fission fragments not to be neglected
67  ! in the jacobian in case of vanishing parent
68  integer, public :: nfiss !< Amount of fission rates
69  integer, private :: nfiss_spont !< Amount of spontaneous fission rates
70  integer, private :: nfiss_n_ind !< Amount of neutron induced fission rates
71  integer, private :: nfiss_bdel !< Amount of beta-delayed fission rates
72  integer, private :: nufiss !< total number of fission neutrons
73 
74  integer, private :: n_nf,n_bf,n_sf !< Amount of individual reactions
75  !
76  ! Public and private fields and methods of the module
77  !
78  public:: &
80  private:: &
87 contains
88 
89 
90  !> Initialize the fission reactions
91  !!
92  !! This subroutine counts and reads fission reactions.
93  !! After calling it \ref fissrate will be filled as well as the integer
94  !! \ref nfiss will store the amount of fission reactions.
95  !!
96  !! @author M. Reichert
97  !! @date 25.01.21
98  subroutine init_fission_rates()
102  implicit none
103  integer :: alloc_stat !< Allocation status flag
104 
105  n_nf=0; n_bf=0; n_sf=0; ! Set counters to 0
106  nfiss=0
107 
108  if (fissflag.ne.0) then
109  if (use_prepared_network) then
111  else
112  !-- Count the amount of fission rates
113  call count_fission_rates()
114 
115  !-- Allocate the fission rate arrays
116  allocate(fissrate(nfiss),stat=alloc_stat)
117  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate" failed.',&
118  "init_fission_rates",190001)
119 
120  !-- Read the fission rates into both arrays
121  call read_fission_rates()
122  call add_fission_fragments()
123 
124  !-- Reorder the fragments, having the ones with the largest
125  !! ch_amount at the beginning.
126  call reorder_fragments()
127 
128  ! Bullet proof fission reactions and normalize the fragments
129  ! if deviation is acceptable (otherwise throw error)
130  ! in case of rounding problems from file reading.
131  if (nfiss .gt. 0) then
133  end if
134 
135  end if
136  !-- Write an overview of the reactions
138  end if
139 
140  end subroutine init_fission_rates
141 
142 
143  !> Check the mass conservation during the fission process.
144  !!
145  !! This subroutine ensures that the total number of nucleons is conserved
146  !! during fission reactions. It calculates the number of nucleons created
147  !! and destroyed for each fission rate, checks for discrepancies against
148  !! a defined error threshold, and raises an exception if the mass
149  !! conservation is violated. If small deviations are within the threshold,
150  !! the subroutine rescales the fragments accordingly.
151  !!
152  !! @author M. Reichert
153  !! @date 17.10.24
155  use global_class, only: isotope, net_names
157  implicit none
158  integer :: i,j !< loop variables
159  real(r_kind) :: n_nucleons_created !< Number of nucleons
160  real(r_kind) :: n_nucleons_destroyed !< Number of nucleons
161  real(r_kind) :: conservation !< Conservation of nucleons
162  real(r_kind) :: norm_factor !< Factor to normalize the fragments
163  real(r_kind),parameter :: error_thresh = 1d-3 !< Error threshold
164 
165  info_entry("check_fission_mass_conservation")
166 
167  do i=1,nfiss
168 
169  n_nucleons_created = 0d0
170  n_nucleons_destroyed = 0d0
171 
172  do j=1,fissrate(i)%dimens
173  ! Now count the number of nucleons, this has to be conserved!
174  if (fissrate(i)%ch_amount(j) .gt. 0) then
175  n_nucleons_created = n_nucleons_created + fissrate(i)%ch_amount(j)*isotope(fissrate(i)%fissparts(j))%mass
176  else
177  n_nucleons_destroyed = n_nucleons_destroyed - fissrate(i)%ch_amount(j)*isotope(fissrate(i)%fissparts(j))%mass
178  end if
179  end do
180 
181  ! Check if the number of nucleons is conserved
182  conservation = n_nucleons_created - n_nucleons_destroyed
183 
184  ! Check if an error should be raised
185  ! Note that small deviations can happen when reading from a file
186  if (abs(conservation) .gt. error_thresh) then
187  call raise_exception("Fission rate does not conserve mass (threshold = 1e-4)! Check your fission fragments! "//new_line("A")//&
188  "Parent: "//trim(adjustl(net_names(fissrate(i)%fissnuc_index)))//new_line("A")//&
189  "Conservation: "//num_to_str(conservation)//new_line("A")//&
190  "Fissmode: "//int_to_str(fissrate(i)%mode),&
191  "check_fission_mass_conservation",190018)
192  end if
193 
194  ! Rescale the fragments
195  norm_factor = n_nucleons_destroyed/n_nucleons_created
196  do j=1,fissrate(i)%dimens
197  ! Scale only fragments
198  if (fissrate(i)%ch_amount(j) .gt. 0) then
199  fissrate(i)%ch_amount(j) = fissrate(i)%ch_amount(j)*norm_factor
200  end if
201  end do
202  end do
203 
204  info_exit("check_fission_mass_conservation")
205 
206  end subroutine check_fission_mass_conservation
207 
208 
209 
210  !> Reorder the fission fragments
211  !!
212  !! Subroutine to reorder the fragments, having the ones with the largest
213  !! ch_amount at the beginning. This is benificial as we can ignore
214  !! some of the entries in the jacobian in case the parent abundance
215  !! is zero.
216  !!
217  !! @author M. Reichert
218  !! @date 22.02.23
219  subroutine reorder_fragments()
221  implicit none
222  integer :: i !< loop variable
223  integer,dimension(:),allocatable :: indices
224 
225  info_entry("reorder_fragments")
226 
227  do i=1,nfiss
228  ! Dont do this for negligible amount of fragments
229  if (fissrate(i)%dimens .le. fiss_neglect+2) cycle
230 
231  ! Allocate indice array
232  if (allocated(indices)) deallocate(indices)
233  allocate(indices(fissrate(i)%dimens-2))
234 
235  ! Order descending according to ch_amount,
236  ! start with the 3rd entry, since the first two are the fissioning nuclei
237  call bubblesort(0,fissrate(i)%dimens-2,fissrate(i)%ch_amount(3:),indices)
238  ! Also reorder the fissparts array
239  call reorder_int(fissrate(i)%fissparts(3:),indices,fissrate(i)%dimens-2)
240 
241  end do
242 
243  info_exit("reorder_fragments")
244 
245  end subroutine reorder_fragments
246 
247 
248  !> Write the amount of individual reactions to the out
249  !!
250  !! The rates are always counted, for a certain verbose level they
251  !! are also printed to the OUT file
252  !!
253  !! @author M. Reichert
254  !! @date 27.01.21
257  implicit none
258  character(len=7) :: tmp !< temporary character for pretty output
259 
260  if (verbose_level .ge. 1) then
261  call write_data_to_std_out("Amount fission rates",int_to_str(nfiss))
262  call write_data_to_std_out("Total number of fission neutrons",int_to_str(nufiss))
263  elseif (verbose_level .ge. 2) then
264  if (nfiss .gt. 0) write(*,"(A)") ""
265  if (nfiss .gt. 0) write(*,"(A)") " Fission rates: "
266  if (nfiss .gt. 0) write(*,"(A)") " |----------------------|"
267  tmp = int_to_str(nfiss)
268  if (nfiss .gt. 0) write(*,"(A)") " | Total :"//adjustr(tmp)//" |"
269  tmp = int_to_str(n_nf)
270  if (n_nf .gt. 0) write(*,"(A)") " | n-induced :"//adjustr(tmp)//" |"
271  tmp = int_to_str(n_bf)
272  if (n_bf .gt. 0) write(*,"(A)") " | b-delayed :"//adjustr(tmp)//" |"
273  tmp = int_to_str(n_sf)
274  if (n_sf .gt. 0) write(*,"(A)") " | spontaneous :"//adjustr(tmp)//" |"
275  if (nfiss .gt. 0) write(*,"(A)") " |----------------------|"
276  if (nfiss .gt. 0) write(*,"(A)") ""
277  end if
278 
279  end subroutine write_reac_verbose_out
280 
281 
282 
283  !> Read the fission reactions and fragment distributions from a binary file
284  !!
285  !! This subroutine reads the fission reactions and fragment distributions
286  !! from a binary, unformatted file. The file is assumed to be created
287  !! beforehand. It is only read when use_prepared_network is set to true.
288  !!
289  !! @author M. Reichert
290  !! @date 21.07.23
295  implicit none
296  character(len=*), intent(in) :: path !< Path to folder with binary files
297  integer :: i !< Loop variable
298  integer :: file_id !< File id
299  integer :: alloc_stat !< Allocation status
300  logical :: is_allocated !< Logical to check if array is allocated
301 
302  if (fissflag .eq. 0) return
303 
304  ! Open an unformatted file
305  file_id = open_unformatted_infile(trim(adjustl(path))//trim(adjustl(fiss_binary_name)))
306 
307  read(file_id) nfiss
308  read(file_id) nufiss
309  read(file_id) n_nf
310  read(file_id) n_bf
311  read(file_id) n_sf
312 
313  ! Allocate the fission rate array
314  allocate(fissrate(nfiss),stat=alloc_stat)
315  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate" failed.',&
316  "read_binary_fission_reaction_data",190001)
317 
318  do i=1,nfiss
319  ! Write all fission rates
320  read(file_id) fissrate(i)%fissnuc_index
321  read(file_id) fissrate(i)%channels
322  read(file_id) fissrate(i)%mode
323  read(file_id) fissrate(i)%src
324  read(file_id) fissrate(i)%dimens
325  read(file_id) fissrate(i)%cached
326  read(file_id) fissrate(i)%averageQ
327  read(file_id) fissrate(i)%reac_type
328 
329  read(file_id) is_allocated
330  if (is_allocated) then
331  ! Allocate fissparts, cscf_ind, q_value, channelprob, and ch_amount array
332  allocate(fissrate(i)%fissparts(fissrate(i)%dimens),stat=alloc_stat)
333  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate(i)%fissparts" failed.',&
334  "read_binary_fission_reaction_data",190001)
335  read(file_id) fissrate(i)%fissparts ! has dimension dimens
336  end if
337 
338  read(file_id) is_allocated
339  if (is_allocated) then
340  allocate(fissrate(i)%cscf_ind(fissrate(i)%dimens,fissrate(i)%dimens),stat=alloc_stat)
341  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate(i)%cscf_ind" failed.',&
342  "read_binary_fission_reaction_data",190001)
343  read(file_id) fissrate(i)%cscf_ind ! has dimension (dimens,dimens)
344  end if
345 
346  read(file_id) fissrate(i)%param ! has dimension 9
347 
348  read(file_id) is_allocated
349  if (is_allocated) then
350  allocate(fissrate(i)%q_value(fissrate(i)%channels),stat=alloc_stat)
351  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate(i)%q_value" failed.',&
352  "read_binary_fission_reaction_data",190001)
353  read(file_id) fissrate(i)%q_value ! has dimension channels
354  end if
355 
356  read(file_id) is_allocated
357  if (is_allocated) then
358  allocate(fissrate(i)%channelprob(fissrate(i)%channels),stat=alloc_stat)
359  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate(i)%channelprob" failed.',&
360  "read_binary_fission_reaction_data",190001)
361  read(file_id) fissrate(i)%channelprob ! has dimension channels
362  end if
363 
364  read(file_id) is_allocated
365  if (is_allocated) then
366  allocate(fissrate(i)%ch_amount(fissrate(i)%dimens),stat=alloc_stat)
367  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate(i)%ch_amount" failed.',&
368  "read_binary_fission_reaction_data",190001)
369  read(file_id) fissrate(i)%ch_amount ! has dimension dimens
370  end if
371 
372 
373  end do
374 
375  close(file_id)
376 
377 
378  end subroutine read_binary_fission_reaction_data
379 
380 
381  !> Save the fission data to a unformatted binary file
382  !!
383  !! This subroutine saves the fission data to a unformatted binary file.
384  !!
385  !! @author M. Reichert
386  !! @date 21.07.23
389  use parameter_class, only: fissflag
390  implicit none
391  character(len=*), intent(in) :: path
392  integer :: i
393  integer :: file_id
394 
395  if (fissflag .eq. 0) return
396  ! Open an unformatted file
397  file_id = open_unformatted_outfile(trim(adjustl(path))//trim(adjustl(fiss_binary_name)))
398  ! Write the fission rates to binary file
399  write(file_id) nfiss
400  write(file_id) nufiss
401  write(file_id) n_nf
402  write(file_id) n_bf
403  write(file_id) n_sf
404 
405 
406  do i=1,nfiss
407  ! Write all fission rates
408  write(file_id) fissrate(i)%fissnuc_index
409  write(file_id) fissrate(i)%channels
410  write(file_id) fissrate(i)%mode
411  write(file_id) fissrate(i)%src
412  write(file_id) fissrate(i)%dimens
413  write(file_id) fissrate(i)%cached
414  write(file_id) fissrate(i)%averageQ
415  write(file_id) fissrate(i)%reac_type
416  write(file_id) allocated(fissrate(i)%fissparts)
417  if (allocated(fissrate(i)%fissparts)) then
418  write(file_id) fissrate(i)%fissparts ! has dimension dimens
419  end if
420  write(file_id) allocated(fissrate(i)%cscf_ind)
421  if (allocated(fissrate(i)%cscf_ind)) then
422  write(file_id) fissrate(i)%cscf_ind ! has dimension (dimens,dimens)
423  end if
424  write(file_id) fissrate(i)%param ! has dimension 9
425  write(file_id) allocated(fissrate(i)%q_value)
426  if (allocated(fissrate(i)%q_value)) then
427  write(file_id) fissrate(i)%q_value ! has dimension channels
428  end if
429  write(file_id) allocated(fissrate(i)%channelprob)
430  if (allocated(fissrate(i)%channelprob)) then
431  write(file_id) fissrate(i)%channelprob ! has dimension channels
432  end if
433  write(file_id) allocated(fissrate(i)%ch_amount)
434  if (allocated(fissrate(i)%ch_amount)) then
435  write(file_id) fissrate(i)%ch_amount ! has dimension dimens
436  end if
437  end do
438 
439  ! Close the file again
440  close(file_id)
441 
443 
444 
445  !> Merge fission rates with larger array.
446  !!
447  !! This subroutine will merge the fission rates.
448  !! Since fission rates are treated separately, there is not really much
449  !! to do. However, in case of beta-delayed fission, the half lifes
450  !! of the beta decays have to be modified to include the fission rates.
451  !!
452  !! @note The other fission rate array \ref fissrate will exist independently
453  !! and are used to calculate the correct equations for the
454  !! fission fragments in \ref jacobian_class::jacobi_init,
455  !! \ref jacobian_class::abchange.
456  !!
457  !! @author M. Reichert
458  !! @date 25.01.21
459  subroutine merge_fission_rates(rrate_array,rrate_length,fiss_count)
463  implicit none
464  type(reactionrate_type),dimension(:),allocatable,intent(inout) :: rrate_array !< Large rate array, containing all reactions
465  integer,intent(inout) :: rrate_length !< length of rrate_array
466  integer,intent(out) :: fiss_count !< Amount of fission rates
467  integer :: new_length !< New length of rrate_array
468 
469  !-- Only do something if there are fission rates
470  if (allocated(fissrate) .and. (.not. use_prepared_network)) then
471  ! New length of the array
472  new_length = rrate_length
473  if (nfiss .ne. 0) then
474  ! Prepare something for the case that fission_format_beta_delayed is
475  ! Set to probability format. In this case, the halflifes of the beta decays
476  ! have to be modified.
477  if (fission_format_beta_delayed .eq. 3) then
478  call modify_halflifes(rrate_array,rrate_length,fissrate,nfiss)
479  ! The length may have gotten modified
480  new_length = rrate_length
481  end if
482  !-- Output the new length
483  rrate_length = new_length
484  end if
485  end if
486  fiss_count = nfiss
487  end subroutine merge_fission_rates
488 
489 
490  !> Modifies half lifes of beta decays to include fission
491  !!
492  !! In case the beta delayed fission rates are given as a probability,
493  !! the beta decays are rescaled to include the fission rates without
494  !! changing the total half life.
495  !! The fission rates are given by:
496  !! \f[
497  !! \lambda_{\text{fiss}} =P_{\text{fiss}} * \lambda_{\beta}
498  !! \f]
499  !! where \f$P_{\text{fiss}}\f$ is the probability of fission and
500  !! \f$\lambda_{\beta}\f$ is the beta decay rate as given initially
501  !! in the Reaclib. The beta decay rate is then modified to
502  !! \f[
503  !! \lambda_{\beta, new} = \left(1-P_{\text{fiss}}\right) * \lambda_{\beta}
504  !! \f]
505  !! There are special cases to consider, namely \f$P_{\text{fiss}}=1\f$ in
506  !! which case the reaclib rate has to be removed completely and
507  !! \f$\lambda_{\beta}\f = 0$ in which case the fission rate has to be removed.
508  !! Note also that fission can have multiple channels, which are by emitting
509  !! different amount of neutrons.
510  !! The fission rates in form of probabilities are given, e.g., in
511  !! [Panov et al. 2005](https://ui.adsabs.harvard.edu/abs/2005NuPhA.747..633P/abstract) or
512  !! [Mumpower et al. 2018](https://ui.adsabs.harvard.edu/abs/2018ApJ...869...14M/abstract).
513  !!
514  !! @author M. Reichert
515  !! @date 30.05.24
516  subroutine modify_halflifes(rrate,rrate_length,fissrate_in,nfiss_in)
521  implicit none
522  type(reactionrate_type),dimension(:),allocatable,intent(inout) :: rrate !< Large rate array, containing all reactions
523  integer,intent(inout) :: rrate_length !< length of rrate_array
524  type(fissionrate_type),dimension(:),allocatable,intent(inout) :: fissrate_in !< Fission rate array
525  integer,intent(inout) :: nfiss_in !< Amount of fission rates
526  integer :: i !< Loop variable
527  real(r_kind),dimension(net_size) :: lambdas !< Lambdas of the beta decay
528  integer :: j !< Loop variable
529  real(r_kind) :: tot_fiss_prob !< Total fission probability
530  integer :: parent_idx !< Index of fissioning nucleus
531  integer :: px_idx !< Channel of the fission rate
532  real(r_kind) :: px !< Probability of the fission rate
533  logical,dimension(rrate_length) :: rrate_mask !< Mask for the rrate array
534  logical,dimension(nfiss_in) :: fissrate_mask !< Mask for the fissrate array
535  type(reactionrate_type),dimension(:),allocatable :: rrate_tmp !< Temporary array to store the rates
536  type(fissionrate_type),dimension(:),allocatable :: fissrate_tmp !< Temporary array to store the fission rates
537  integer :: new_rrate_length !< New length of the rrate array
538  integer :: new_nfiss_in !< New amount of fission rates
539  integer :: alloc_stat !< Allocation status
540  real(r_kind) :: lambda_rate !< Rate of the beta decay
541 
542  info_entry("modify_halflifes")
543 
544  lambdas(:) = 0d0
545 
546  fissrate_mask(:) = .true.
547 
548  ! Ensure that there are reactions in rrate
549  if (allocated(rrate)) then
550  rrate_mask(:) = .true.
551  ! Modify beta decays in rrate array and get the half lifes of the beta decays
552  do i=1,rrate_length
553 
554  ! Ignore things that are definitely not beta decays
555  ! and also theoretical weak rates
556  if ((rrate(i)%reac_src .eq. rrs_twr) .or. &
557  (rrate(i)%reac_src .eq. rrs_nu) .or. &
558  (rrate(i)%reac_src .eq. rrs_fiss) .or. &
559  (rrate(i)%reac_src .eq. rrs_aext) .or. &
560  (rrate(i)%reac_src .eq. rrs_detb)) cycle
561 
562  if (rrate(i)%reac_type.eq.rrt_betm) then
563  part_loop: do j=1,get_nr_reactants(rrate(i)%group)
564  if ((rrate(i)%parts(j).ne.ineu) .and. (rrate(i)%parts(j).ne.ipro)) then
565  ! Get the total fission fraction over all channels (P0n, P1n, ...)
566  tot_fiss_prob = sum(beta_delayed_fiss_probs(rrate(i)%parts(j),:))
567 
568  ! Take care of reaclib type reactions
569  if ((rrate(i)%reac_src .eq. rrs_reacl) .or. &
570  (rrate(i)%reac_src .eq. rrs_wext)) then
571  lambda_rate = dexp(rrate(i)%param(1))
572  lambdas(rrate(i)%parts(j)) = lambdas(rrate(i)%parts(j))+lambda_rate
573  if ((1d0-tot_fiss_prob) .ne. 0d0) then
574  rrate(i)%param(1) = rrate(i)%param(1)+dlog(1d0-tot_fiss_prob)
575  else
576  ! Remove the rate, it will become a fission rate
577  rrate_mask(i) = .false.
578  end if
579  ! Take care of tabulated rates
580  else if (rrate(i)%reac_src .eq. rrs_tabl) then
581 
582  ! The rate should be constant so just take 1GK
583  call tabulated_index(1d0)
584  call calculate_tab_rate(rrate(i),1d0,lambda_rate)
585  ! Save it
586  lambdas(rrate(i)%parts(j)) = lambdas(rrate(i)%parts(j))+lambda_rate
587  if ((1d0-tot_fiss_prob) .ne. 0d0) then
588  call multiply_tab_rate_by_factor(rrate(i),1d0-tot_fiss_prob)
589  else
590  ! Remove the rate, it will become a fission rate
591  rrate_mask(i) = .false.
592  end if
593  else
594  call raise_exception('Unknown reac_src in modify_halflifes.',&
595  "modify_halflifes",190014)
596  end if
597  ! Go out of the loop
598  exit part_loop
599  end if
600  end do part_loop
601  end if
602  end do
603 
604  ! Reduce the rrate array to the correct size
605  new_rrate_length = count(rrate_mask)
606  if (new_rrate_length .ne. rrate_length) then
607 
608  ! Say something if the verbose level is high enough
609  if (verbose_level .ge. 2) then
610  write(*,*) "Reducing the rate array to the correct size by removing "//&
611  int_to_str(rrate_length-new_rrate_length)//&
612  " beta-decays and putting it into fission rates."
613  end if
614 
615  ! Allocate a temporary array to store the content of rrate
616  allocate(rrate_tmp(new_rrate_length),stat=alloc_stat)
617  if ( alloc_stat /= 0) call raise_exception('Allocation of "rrate_tmp" failed.',&
618  "modify_halflifes",190001)
619 
620  rrate_tmp(1:new_rrate_length) = pack(rrate,rrate_mask)
621  deallocate(rrate,stat=alloc_stat)
622  if ( alloc_stat /= 0) call raise_exception('Deallocation of "rrate" failed.',&
623  "modify_halflifes",190002)
624 
625  allocate(rrate(new_rrate_length),stat=alloc_stat)
626  if ( alloc_stat /= 0) call raise_exception('Allocation of "rrate" failed.',&
627  "modify_halflifes",190001)
628 
629  rrate(1:new_rrate_length) = rrate_tmp(1:new_rrate_length)
630  deallocate(rrate_tmp,stat=alloc_stat)
631  if ( alloc_stat /= 0) call raise_exception('Deallocation of "rrate_tmp" failed.',&
632  "modify_halflifes",190002)
633  rrate_length = new_rrate_length
634  end if
635  end if
636 
637  ! Make the correct lambdas in the fission array
638  do i=1,size(fissrate_in)
639  if (fissrate_in(i)%reac_type.eq.rrt_bf) then
640  ! Beta-delayed fission
641  parent_idx = fissrate_in(i)%fissnuc_index
642  px_idx = int(fissrate_in(i)%released_n+1d0)
643  px = beta_delayed_fiss_probs(parent_idx,px_idx)
644  if (lambdas(parent_idx) .eq. 0d0) then
645  ! Remove the rate, the parent is not beta-decaying
646  fissrate_mask(i) = .false.
647  else
648  ! Fissrate
649  fissrate_in(i)%param(:) = 0d0
650  fissrate_in(i)%param(1) = dlog(px * lambdas(parent_idx))
651  end if
652  end if
653  end do
654 
655  ! Reduce the fission rate array to the correct size
656  new_nfiss_in = count(fissrate_mask)
657  if (new_nfiss_in .ne. nfiss_in) then
658  ! Say something if the verbose level is high enough
659  if (verbose_level .ge. 2) then
660  write(*,*) "Reducing the fission rate array to the correct size by removing "//&
661  int_to_str(nfiss_in-new_nfiss_in)//" beta-delayed fission rates."
662  end if
663  ! Allocate a temporary array to store the content of fissrate
664  allocate(fissrate_tmp(new_nfiss_in),stat=alloc_stat)
665  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_tmp" failed.',&
666  "modify_halflifes",190001)
667  j=1
668  do i=1,nfiss_in
669  if (fissrate_mask(i)) then
670  ! Allocate all the necessary stuff in fissrate_tmp
671  allocate(fissrate_tmp(j)%fissparts(fissrate_in(i)%dimens),stat=alloc_stat)
672  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_tmp(j)%fissparts" failed.',&
673  "modify_halflifes",190001)
674  allocate(fissrate_tmp(j)%cscf_ind(fissrate_in(i)%dimens,fissrate_in(i)%dimens),stat=alloc_stat)
675  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_tmp(j)%cscf_ind" failed.',&
676  "modify_halflifes",190001)
677  allocate(fissrate_tmp(j)%q_value(fissrate_in(i)%channels),stat=alloc_stat)
678  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_tmp(j)%q_value" failed.',&
679  "modify_halflifes",190001)
680  allocate(fissrate_tmp(j)%channelprob(fissrate_in(i)%channels),stat=alloc_stat)
681  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_tmp(j)%channelprob" failed.',&
682  "modify_halflifes",190001)
683  allocate(fissrate_tmp(j)%ch_amount(fissrate_in(i)%dimens),stat=alloc_stat)
684  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_tmp(j)%ch_amount" failed.',&
685  "modify_halflifes",190001)
686  ! Finally copy... A "pack" would be easier, but we need to ensure the allocation of the arrays inside the types
687  fissrate_tmp(j) = fissrate_in(i)
688  j = j+1
689  end if
690  end do
691 
692  ! fissrate_tmp(1:new_nfiss_in) = pack(fissrate_in,fissrate_mask)
693  deallocate(fissrate_in,stat=alloc_stat)
694  if ( alloc_stat /= 0) call raise_exception('Deallocation of "fissrate_in" failed.',&
695  "modify_halflifes",190002)
696  allocate(fissrate_in(new_nfiss_in),stat=alloc_stat)
697  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_in" or failed.',&
698  "modify_halflifes",190001)
699 
700  ! Copy back from temporary array
701  do i=1,new_nfiss_in
702  allocate(fissrate_in(i)%fissparts(fissrate_tmp(i)%dimens),stat=alloc_stat)
703  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_in(i)%fissparts" failed.',&
704  "modify_halflifes",190001)
705  allocate(fissrate_in(i)%cscf_ind(fissrate_tmp(i)%dimens,fissrate_tmp(i)%dimens),stat=alloc_stat)
706  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_in(i)%cscf_ind" failed.',&
707  "modify_halflifes",190001)
708  allocate(fissrate_in(i)%q_value(fissrate_tmp(i)%channels),stat=alloc_stat)
709  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_in(i)%q_value" failed.',&
710  "modify_halflifes",190001)
711  allocate(fissrate_in(i)%channelprob(fissrate_tmp(i)%channels),stat=alloc_stat)
712  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_in(i)%channelprob" failed.',&
713  "modify_halflifes",190001)
714  allocate(fissrate_in(i)%ch_amount(fissrate_tmp(i)%dimens),stat=alloc_stat)
715  if ( alloc_stat /= 0) call raise_exception('Allocation of "fissrate_in(i)%ch_amount" failed.',&
716  "modify_halflifes",190001)
717  fissrate_in(i) = fissrate_tmp(i)
718  end do
719 
720 
721  ! fissrate_in(1:new_nfiss_in) = fissrate_tmp(1:new_nfiss_in)
722  deallocate(fissrate_tmp,stat=alloc_stat)
723  if ( alloc_stat /= 0) call raise_exception('Deallocation of "fissrate_tmp" or failed.',&
724  "modify_halflifes",190002)
725  nfiss_in = new_nfiss_in
726  end if
727 
728  ! Deallocate the beta-delayed fission probabilities
729  ! as everything is now in the fission rate array
730  deallocate(beta_delayed_fiss_probs,stat=alloc_stat)
731  if ( alloc_stat /= 0) call raise_exception('Deallocation of "beta_delayed_fiss_probs" failed.',&
732  "modify_halflifes",190002)
733 
734  info_exit("modify_halflifes")
735  end subroutine modify_halflifes
736 
737 
738 
739  !> Count the amount of fission rates
740  !!
741  !! This subroutine counts the amount of fission rates and
742  !! stores the result in \ref nfiss.
743  !! In case that a new fission type will be implemented,
744  !! the reaction rates should be counted here.
745  !! The different formats for the different types of fission reactions are:
746  !! <table>
747  !! <caption id="multi_row">Fission formats</caption>
748  !! <tr><th> Type <th> Value <th> Description
749  !! <tr><td> Spontaneous <td> 0 <td> No rates are read
750  !! <tr><td> Spontaneous <td> 1 <td> Reaclib format
751  !! <tr><td> Spontaneous <td> 2 <td> Half life format
752  !! <tr><td> n-induced <td> 0 <td> No rates are read
753  !! <tr><td> n-induced <td> 1 <td> Reaclib format
754  !! <tr><td> \f$\beta\f$-delayed <td> 0 <td> No rates are read
755  !! <tr><td> \f$\beta\f$-delayed <td> 1 <td> Reaclib format
756  !! <tr><td> \f$\beta\f$-delayed <td> 2 <td> Half life format
757  !! <tr><td> \f$\beta\f$-delayed <td> 3 <td> Probability format
758  !! </table>
759  !!
760  !! @see \ref read_fission_rates
761  !!
762  !! @author M. Reichert
763  !! @date 25.01.21
764  subroutine count_fission_rates()
768  use global_class, only: net_size
770  implicit none
771  integer :: alloc_stat !< Allocation status
772 
773  info_entry("count_fission_rates")
774 
775  ! Spontaneous fission rates
776  select case(fission_format_spontaneous)
777  case(0)
778  nfiss_spont = 0
779  case(1)
781  case(2)
783  case default
784  call raise_exception("Fission format for spontaneous fission rates not implemented, got '"//&
785  int_to_str(fission_format_spontaneous)//"'. Change the "//&
786  "'fission_format_spontaneous' parameter.",&
787  "count_fission_rates",190010)
788  end select
789 
790  ! Neutron induced fission rates
791  select case(fission_format_n_induced)
792  case(0)
793  nfiss_n_ind = 0
794  case(1)
796  case default
797  call raise_exception("Fission format for neutron-induced fission rates not implemented, got '"//&
798  int_to_str(fission_format_n_induced)//"'. Change the "//&
799  "'fission_format_n_induced' parameter.",&
800  "count_fission_rates",190010)
801  end select
802 
803  ! Beta-delayed fission rates
804  select case(fission_format_beta_delayed)
805  case(0)
806  nfiss_bdel = 0
807  case(1)
809  case(2)
811  case(3)
813  ! Initialize an array to store the beta-delayed fission probabilities
814  allocate(beta_delayed_fiss_probs(net_size,amount_cols),stat=alloc_stat)
815  if ( alloc_stat /= 0) call raise_exception('Allocation of "beta_delayed_fiss_probs" failed.',&
816  "count_fission_rates",190001)
817  beta_delayed_fiss_probs(:,:) = 0d0
818  case default
819  call raise_exception("Fission format for beta-delayed fission rates not implemented, got '"//&
820  int_to_str(fission_format_beta_delayed)//"'. Change the "//&
821  "'fission_format_beta_delayed' parameter.",&
822  "count_fission_rates",190010)
823  end select
824 
825  ! Calculate the total amount of fission rates
827 
828  info_exit("count_fission_rates")
829  end subroutine count_fission_rates
830 
831 
832  !> Count the amount of fission rates in reaclib format
833  !!
834  !! This subroutine counts the amount of fission rates in reaclib format
835  !! and stores the result in count_rates. This is necessary to allocate
836  !! the fission array with the correct length. The subroutine can be called
837  !! for any kind of fission (spontaneous, n-induced, beta-delayed).
838  !!
839  !! \b Edited:
840  !! - 30.05.2024 (MR): Made this its own subroutine to add more file formats
841  !! .
842  subroutine count_fission_rates_reaclib_format(fission_rate_file,count_rates)
844  use benam_class, only: benam
845  use format_class
846  implicit none
847  character(len=*), intent(in) :: fission_rate_file !< File containing fission rates
848  integer, intent(out) :: count_rates !< Amount of fission rates
849  integer :: j !< Loop variable
850  integer :: read_stat !< Read status
851  integer :: fissionlib !< File id of fisionrates
852  character(5), dimension(6) :: parts !< Participating nuclei names
853  integer, dimension(6) :: parts_index !< Participating nuclei indices
854  real(r_kind), dimension(9) :: params !< Reaclib fitting parameter
855  character(4) :: src !< Reaclib source label
856  character(1) :: res !< Reaclib weak flag label
857  character(1) :: rev !< Reaclib reverse label
858  real(r_kind) :: q !< Reaclib Q-Value
859  integer :: grp !< Reaclib chapter
860  integer :: ifiss !< reaction rate counter
861 
862  ! Counter for fission rates
863  ifiss = 0
864 
865  ! Open fission file
866  fissionlib = open_infile(fission_rate_file)
867 
868  ! Count the rates
869  fission: do
870  read(fissionlib,my_format(1), iostat = read_stat) &
871  grp, parts(1:6), src, res, rev, q
872  if (read_stat /= 0) exit
873  read(fissionlib,"(4E13.6)") params(1:4)
874  read(fissionlib,"(5E13.6)") params(5:9)
875  if (grp.ne.0) cycle fission
876  parts_index = 0
877  indices: do j=1,6
878  if (parts(j) .eq. ' ') exit indices
879  parts_index(j) = benam(parts(j))
880  ! parts_index(i) = 0 if nuclide i is not in network
881  if (parts_index(j) .eq. 0) cycle fission
882  end do indices
883  ifiss = ifiss + 1
884  end do fission
885 
886  ! Close the fission file again
887  close(fissionlib)
888 
889  count_rates = ifiss
891 
892 
893  !> Count the amount of fission rates in half-life format
894  !!
895  !! This subroutine counts the amount of fission rates in half-life format
896  !! and stores the result in count_rates. This is necessary to allocate
897  !! the fission array with the correct length. The subroutine can be called
898  !! for spontaneous and beta-delayed fission.
899  !! An example of an entry can be:
900  !! \file{
901  !! th198 4.760787e-09 kh20
902  !! th199 2.808520e-08 kh20
903  !! th200 2.841403e-08 kh20
904  !! ...}
905  !! where the first columns gives the nucleus, the second the halflife in seconds
906  !! and the third the source. Note that in this format, no beta-delayed neutrons
907  !! can be specified.
908  !!
909  !! @author M. Reichert
910  !! @date 30.05.24
911  subroutine count_fission_rates_halflife_format(fission_rate_file,count_rates)
913  use benam_class, only: benam
914  use format_class
915  implicit none
916  character(len=*), intent(in) :: fission_rate_file !< File containing fission rates
917  integer, intent(out) :: count_rates !< Amount of fission rates
918  integer :: j !< Loop variable
919  integer :: read_stat !< Read status
920  integer :: fissionlib !< File id of fisionrates
921  character(5), dimension(6) :: parts !< Participating nuclei names
922  integer, dimension(6) :: parts_index !< Participating nuclei indices
923  integer :: ifiss !< reaction rate counter
924  real(r_kind), dimension(9) :: params !< Reaclib fitting parameter
925  character(4) :: src !< Reaclib source label
926 
927  ! Counter for fission rates
928  ifiss = 0
929 
930  ! Open fission file
931  fissionlib = open_infile(fission_rate_file)
932 
933  ! Count the rates
934  fission_hl: do
935  ! Set parts to empty strings
936  parts(1:6) = ' '
937  params(:) = 0d0
938 
939  ! An example line could be: pa231 3.446020e+23 kh20
940  read(fissionlib, *, iostat = read_stat) &
941  parts(1), params(1), src
942  if (read_stat /= 0) exit
943 
944  parts_index = 0
945  indices_hl: do j=1,6
946  if (parts(j) .eq. ' ') exit indices_hl
947  parts_index(j) = benam(parts(j))
948  ! parts_index(i) = 0 if nuclide i is not in network
949  if (parts_index(j) .eq. 0) cycle fission_hl
950  end do indices_hl
951  ifiss = ifiss + 1
952  end do fission_hl
953 
954  ! Close the fission file again
955  close(fissionlib)
956 
957  ! Store the amount of fission rates
958  count_rates = ifiss
960 
961 
962  !> Count the amount of fission rates in probability format
963  !!
964  !! This subroutine counts the amount of fission rates in probability format
965  !! and stores the result in count_rates. This is necessary to allocate
966  !! the fission array with the correct length. The subroutine can be called
967  !! for beta-delayed fission.
968  !! An example of an entry can be:
969  !! \file{
970  !! pa291 mp18
971  !! 0.000 0.008 0.000 0.015 0.000 0.018 0.000 0.025 0.000 0.003
972  !! pa292 mp18
973  !! 0.000 0.001 0.002 0.000 0.004 0.000 0.006 0.000 0.018 0.000
974  !! pa293 mp18
975  !! 0.239 0.001 0.000 0.009 0.000 0.010 0.000 0.014 0.000 0.009
976  !! ...}
977  !! where the first line of an entry gives nucleus name and the source. The second line
978  !! gives the probabilities of the fission channels (i.e., P0nf, P1nf, ...).
979  !! Note that there is a maximum number of columns (i.e., neutron emission) set to 30 here.
980  !! Throughout the file, the amount of possible channels have to stay the same, but they
981  !! can be different for two different files. For example, for Panov et al. 2005 the file
982  !! could look like:
983  !! \file{
984  !! u259 pa05
985  !! 0.990
986  !! u260 pa05
987  !! 0.020
988  !! u261 pa05
989  !! 0.990
990  !! ...}.
991  !!
992  !! @author M. Reichert
993  !! @date 30.05.24
994  subroutine count_fission_rates_probability_format(fission_rate_file,count_rates,nr_cols)
996  use benam_class, only: benam
998  use format_class
999  implicit none
1000  character(len=*), intent(in) :: fission_rate_file !< File containing fission rates
1001  integer, intent(out) :: count_rates !< Amount of fission rates
1002  integer, intent(out) :: nr_cols !< Number of columns in the file
1003  integer,parameter :: maxcols = 30!< Maximum number of columns
1004  integer :: j !< Loop variable
1005  integer :: read_stat !< Read status
1006  integer :: fissionlib !< File id of fisionrates
1007  character(5) :: parent !< Participating nuclei names
1008  integer :: idx_parent !< Participating nuclei indices
1009  integer :: ifiss !< reaction rate counter
1010  real(r_kind), dimension(maxcols):: buff !< Reaclib fitting parameter
1011  character(500) :: dummy !< Reaclib source label
1012  character(4) :: src !< Reaclib source label
1013  integer :: fiss_probs !< Number of fission probabilities not equal zero
1014 
1015  ! Counter for fission rates
1016  ifiss = 0
1017 
1018  ! Open fission file
1019  fissionlib = open_infile(fission_rate_file)
1020 
1021  ! Count the rates
1022  fission_prob: do
1023  buff(:) = -1d0
1024 
1025  ! An example entry could be: pa250 pa05
1026  ! 0.010
1027  read(fissionlib, * , iostat = read_stat) parent, src
1028 
1029  if (read_stat /= 0) exit
1030 
1031  ! Count columns, maximum allowed ones are 30
1032  if (ifiss .eq. 0) then
1033  read(fissionlib,'(A)', iostat = read_stat) dummy
1034  do j=1,maxcols
1035  read(dummy,*,iostat=read_stat) buff(1:j)
1036  if (read_stat .ne. 0) exit
1037  end do
1038  ! Count the number of columns
1039  nr_cols = count(buff .ne. -1d0)
1040  else
1041  read(fissionlib,*, iostat = read_stat) buff(1:nr_cols)
1042  if (read_stat .ne. 0) call raise_exception('Reading the fission probabilities failed.',&
1043  "count_fission_rates_probability_format",190012)
1044  end if
1045 
1046  ! Count the number of fission probabilities not equal zero
1047  fiss_probs = count((buff .ne. -1d0) .and. (buff .ne. 0d0))
1048 
1049  ! Check if the parent is included in the network
1050  idx_parent = benam(parent)
1051 
1052  if (idx_parent .eq. 0) cycle fission_prob
1053 
1054  ! Count the amount of fission rates that have a
1055  ! probability not equal zero
1056  ifiss = ifiss + fiss_probs
1057  end do fission_prob
1058 
1059  ! Close the fission file again
1060  close(fissionlib)
1061 
1062  ! Store the amount of fission rates
1063  count_rates = ifiss
1065 
1066 
1067  !> Initializes the rates with fragments
1068  !!
1069  !! This routine initializes the fission rates with the specified fragments.
1070  !! The fragments can differ for the types of fission.
1071  !!
1072  !!
1073  !!
1074  !!
1075  !! \b Edited:
1076  !! - 31.05.2024 (MR): Created this subroutine from code parts contained in other routines
1077  !! .
1079  use parameter_class, only: fissflag, &
1085  use global_class, only: isotope
1088  implicit none
1089  integer :: neutfission=0 !< File IDs for abla fiss. distr. file
1090  integer :: betafission=0 !< File IDs for abla fiss. distr. file
1091  integer :: fissindex !< Index for current fission rate
1092  integer :: astat !< Allocation status
1093  real(r_kind) :: q !< Reaclib Q-Value
1094  integer :: nfrac_distr !< Number of fragment distributions in file
1095 
1096 
1097  !-- Open the abla files, containing probabilities of the fiss. fragments
1098  if (fissflag .eq. 3) then
1100  ! Create the same for beta-delayed fission without explicitely reading the file again
1101  nfrac_distr = size(fissfrags_n_induced)
1102  allocate(fissfrags_beta_delayed(nfrac_distr),stat=astat)
1103  if (astat /= 0) call raise_exception('Allocation of "fissfrags_bdel" failed.',&
1104  "add_fission_fragments",190001)
1106  else if (fissflag .eq. 4) then
1107  ! Read the fission fragment files if necessary
1108  ! n_induced
1109  if ((fission_frag_n_induced .eq. 3) .and. (fission_format_n_induced .ne. 0)) then
1111  end if
1112  ! beta-delayed
1113  if ((fission_frag_beta_delayed .eq. 3) .and. (fission_format_beta_delayed .ne. 0)) then
1115  end if
1116  ! spontaneous
1117  if ((fission_frag_spontaneous .eq. 3) .and. (fission_format_spontaneous .ne. 0)) then
1119  end if
1120  else if (fissflag .eq. 5) then
1121  neutfission= open_infile(nfission_file)
1122  betafission= open_infile(bfission_file)
1123  end if
1124 
1125  ! Loop through reactions and add fission fragments
1126  do fissindex=1,nfiss
1127 
1128  if (fissrate(fissindex)%reac_type.eq.rrt_nf) then ! neutron-induced fission
1129  select case (fissflag)
1130  case(1)
1131  call fiss_dist(fissrate(fissindex))
1132  case(2)
1133  call kodtakdist(fissrate(fissindex))
1134  case(3)
1135  call file_fiss_frag(fissrate(fissindex),2)
1136  case(4)
1137  select case (fission_frag_n_induced)
1138  case(1)
1139  call fiss_dist(fissrate(fissindex))
1140  case(2)
1141  call kodtakdist(fissrate(fissindex))
1142  case(3)
1144  case default
1145  call raise_exception("Fission fragment flag ("//trim(adjustl(int_to_str(fission_frag_n_induced)))&
1146  //") not implemented yet. "//&
1147  "Set it to a supported value!",&
1148  "add_fission_fragments",&
1149  190003)
1150  end select
1151  case(5)
1152  call abla_nfiss(fissindex,isotope(fissrate(fissindex)%fissnuc_index)%mass, &
1153  isotope(fissrate(fissindex)%fissnuc_index)%p_nr,neutfission,q)
1154  case default
1155  call raise_exception("Fission flag ("//trim(adjustl(int_to_str(fissflag)))&
1156  //") not implemented yet. "//&
1157  "Set it to a supported value!",&
1158  "add_fission_fragments",&
1159  190003)
1160  end select
1161  else if (fissrate(fissindex)%reac_type.eq.rrt_sf) then ! spontaneous fission
1162  select case (fissflag)
1163  case(1)
1164  call fiss_dist(fissrate(fissindex))
1165  case(2)
1166  call kodtakdist(fissrate(fissindex))
1167  case(3)
1168  call kodtakdist(fissrate(fissindex))
1169  case(4)
1170  select case (fission_frag_spontaneous)
1171  case(1)
1172  call fiss_dist(fissrate(fissindex))
1173  case(2)
1174  call kodtakdist(fissrate(fissindex))
1175  case(3)
1177  case default
1178  call raise_exception("Fission fragment flag ("//trim(adjustl(int_to_str(fission_frag_spontaneous)))&
1179  //") not implemented yet. "//&
1180  "Set it to a supported value!",&
1181  "add_fission_fragments",&
1182  190003)
1183  end select
1184  case(5)
1185  call abla_betafiss(fissindex,isotope(fissrate(fissindex)%fissnuc_index)%mass, &
1186  isotope(fissrate(fissindex)%fissnuc_index)%p_nr,betafission,q)
1187  case default
1188  call raise_exception("Fission flag ("//trim(adjustl(int_to_str(fissflag)))&
1189  //") not implemented yet. "//&
1190  "Set it to a supported value!",&
1191  "add_fission_fragments",&
1192  190003)
1193  end select
1194  else if (fissrate(fissindex)%reac_type.eq.rrt_bf) then ! beta-delayed fission
1195  select case (fissflag)
1196  case(1)
1197  call fiss_dist(fissrate(fissindex))
1198  case(2)
1199  call kodtakdist(fissrate(fissindex))
1200  case(3)
1201  call file_fiss_frag(fissrate(fissindex),2)
1202  case(4)
1203  select case (fission_frag_beta_delayed)
1204  case(1)
1205  call fiss_dist(fissrate(fissindex))
1206  case(2)
1207  call kodtakdist(fissrate(fissindex))
1208  case(3)
1210  case default
1211  call raise_exception("Fission fragment flag ("//trim(adjustl(int_to_str(fission_frag_beta_delayed)))&
1212  //") not implemented yet. "//&
1213  "Set it to a supported value!",&
1214  "add_fission_fragments",&
1215  190003)
1216  end select
1217  case(5)
1218  call abla_betafiss(fissindex,isotope(fissrate(fissindex)%fissnuc_index)%mass, &
1219  isotope(fissrate(fissindex)%fissnuc_index)%p_nr,betafission,q)
1220  case default
1221  call raise_exception("Fission flag ("//trim(adjustl(int_to_str(fissflag)))&
1222  //") not implemented yet. "//&
1223  "Set it to a supported value!",&
1224  "add_fission_fragments",&
1225  190003)
1226  end select
1227  end if
1228 
1229 
1230  end do
1231 
1232  ! Clean up
1233  ! Close the neutron and betafission files again
1234  if (neutfission.gt.0) call close_io_file(neutfission,nfission_file)
1235  if (betafission.gt.0) call close_io_file(betafission,bfission_file)
1236  ! Deallocate the fission fragment arrays in case they were read from file
1237  if (allocated(fissfrags_beta_delayed)) then
1238  deallocate(fissfrags_beta_delayed,stat=astat)
1239  if (astat.ne.0) call raise_exception("Could not deallocate fissfrags_beta_delayed array.",&
1240  "add_fission_fragments",190002)
1241  end if
1242  if (allocated(fissfrags_n_induced)) then
1243  deallocate(fissfrags_n_induced,stat=astat)
1244  if (astat.ne.0) call raise_exception("Could not deallocate fissfrags_n_induced array.",&
1245  "add_fission_fragments",190002)
1246  end if
1247  if (allocated(fissfrags_spontaneous)) then
1248  deallocate(fissfrags_spontaneous,stat=astat)
1249  if (astat.ne.0) call raise_exception("Could not deallocate fissfrags_spontaneous array.",&
1250  "add_fission_fragments",190002)
1251  end if
1252  end subroutine add_fission_fragments
1253 
1254 
1255 
1256 
1257  !> Read the fission rates, splitted into different types of fission
1258  !!
1259  !! This routine serves as interface between the reading routines and
1260  !! the different fission formats and types. In case a new type of
1261  !! fission will be implemented, the reaction rates should be read here.
1262  !! The different formats for the different types of fission reactions are:
1263  !! <table>
1264  !! <caption id="multi_row">Fission formats</caption>
1265  !! <tr><th> Type <th> Value <th> Description
1266  !! <tr><td> Spontaneous <td> 0 <td> No rates are read
1267  !! <tr><td> Spontaneous <td> 1 <td> Reaclib format
1268  !! <tr><td> Spontaneous <td> 2 <td> Half life format
1269  !! <tr><td> n-induced <td> 0 <td> No rates are read
1270  !! <tr><td> n-induced <td> 1 <td> Reaclib format
1271  !! <tr><td> \f$\beta\f$-delayed <td> 0 <td> No rates are read
1272  !! <tr><td> \f$\beta\f$-delayed <td> 1 <td> Reaclib format
1273  !! <tr><td> \f$\beta\f$-delayed <td> 2 <td> Half life format
1274  !! <tr><td> \f$\beta\f$-delayed <td> 3 <td> Probability format
1275  !! </table>
1276  !!
1277  !! @author M. Reichert
1278  !! @date 31.05.2024
1279  subroutine read_fission_rates()
1284  implicit none
1285  integer :: fisscount !< Amount of fission rates
1286 
1287  ! Keep track of fission rates
1288  fisscount = 1
1289 
1290  ! Read the spontaneous fission rates
1291  select case (fission_format_spontaneous)
1292  case(0)
1293  ! Dont read anything
1294  continue
1295  case(1)
1296  ! Read the spontaneous fission rates in reaclib format
1298  case(2)
1299  ! Read the spontaneous fission rates in halflife format
1301  case default
1302  call raise_exception("Fission format for spontaneous fission rates not implemented, got '"//&
1303  int_to_str(fission_format_spontaneous)//"'. Change the "//&
1304  "'fission_format_spontaneous' parameter.",&
1305  "read_fission_rates",190010)
1306  end select
1307 
1308  ! Read the neutron-induced fission rates
1309  select case (fission_format_n_induced)
1310  case(0)
1311  ! Dont read anything
1312  continue
1313  case(1)
1315  case default
1316  call raise_exception("Fission format for neutron-induced fission rates not implemented, got '"//&
1317  int_to_str(fission_format_n_induced)//"'. Change the "//&
1318  "'fission_format_n_induced' parameter.",&
1319  "read_fission_rates",190010)
1320  end select
1321 
1322  ! Read the beta-delayed fission rates
1323  select case (fission_format_beta_delayed)
1324  case(0)
1325  ! Dont read anything
1326  continue
1327  case(1)
1328  ! Read the beta-delayed fission rates in reaclib format
1330  case(2)
1331  ! Read the beta-delayed fission rates in halflife format
1333  case(3)
1334  ! Read the beta-delayed fission rates in probability format
1336  case default
1337  call raise_exception("Fission format for beta-delayed fission rates not implemented, got '"//&
1338  int_to_str(fission_format_beta_delayed)//"'. Change the "//&
1339  "'fission_format_beta_delayed' parameter.",&
1340  "read_fission_rates",190010)
1341  end select
1342 
1343  end subroutine read_fission_rates
1344 
1345 
1346  !> Reads fission rates in Reaclib format
1347  !!
1348  !! This subroutine reads the fission rates that are specified in the file
1349  !! parameter_class::fission_rates. Fission rates are implemented with the same
1350  !! fits and a similar format as usual reaclib rates (see reaclib_rate_module::read_reaclib).
1351  !! An example looks like:
1352  !! \file{
1353  !! th256 ms99w 0.00000E+00
1354  !! 1.988512E-02 0.000000E+00 0.000000E+00 0.000000E+00
1355  !! 0.000000E+00 0.000000E+00 0.000000E+00
1356  !! th257 ms99w 0.00000E+00
1357  !! -1.483947E+00 0.000000E+00 0.000000E+00 0.000000E+00
1358  !! 0.000000E+00 0.000000E+00 0.000000E+00
1359  !! ...}
1360  !! The chapter structure is the same as in reaclib, but only the parent nucleus
1361  !! has an entry. The products are given by the respective fission fragment
1362  !! distribution.
1363  !!
1364  !! @returns \ref fissrate filled with fission rates
1365  !! @author M. Eichler
1366  !!
1367  !! \b Edited:
1368  !! - 25.01.21 (MR): Moved from init_network to this new independent subroutine
1369  !! - 27.05.24 (MR): Moved initializing fragments to independent subroutine
1370  !! -
1371  subroutine read_fission_rates_reaclib_format(fission_path,reac_type,start_idx)
1372  use parameter_class, only: fissflag
1373  use benam_class, only: benam
1374  use global_class, only: isotope, ineu
1376  use format_class
1377  use error_msg_class
1378  implicit none
1379  character(len=*), intent(in) :: fission_path !< Path to fission rates file
1380  integer, intent(in) :: reac_type !< Reaction type
1381  integer, intent(inout) :: start_idx !< Start index for fission rates
1382  integer :: read_stat !< Read status
1383  integer :: fissionlib !< File id of fisionrates
1384  character(5), dimension(6) :: parts !< Participating nuclei names
1385  integer, dimension(6) :: parts_index !< Participating nuclei indices
1386  real(r_kind), dimension(9) :: params !< Reaclib fitting parameter
1387  character(4) :: src !< Reaclib source label
1388  character(1) :: res !< Reaclib weak flag label
1389  character(1) :: rev !< Reaclib reverse label
1390  real(r_kind) :: q !< Reaclib Q-Value
1391  integer :: grp !< Reaclib chapter
1392  integer :: group_index !< Storage for the current chapter
1393  integer :: fissindex !< Index for current fission rate
1394  integer :: j !< Loop variable
1395 
1396 
1397 
1398  !-- Open the fission library file
1399  fissionlib = open_infile(fission_path)
1400 
1401  ! make sure counting index for reaction rates continues for fission rates
1402  fissindex = start_idx
1403  fission_loop: do
1404  read(fissionlib,my_format(1), iostat = read_stat) &
1405  grp, parts(1:6), src, res, rev, q
1406  if (read_stat /= 0) exit fission_loop
1407  read(fissionlib,"(4E13.6)") params(1:4)
1408  read(fissionlib,"(5E13.6)") params(5:9)
1409 
1410  select case (grp)
1411  case (1:11)
1412  group_index = grp
1413  cycle fission_loop
1414  case default
1415  parts_index = 0
1416  inner_fission: do j=1,6
1417  if (parts(j) .eq. ' ') exit inner_fission
1418  parts_index(j) = benam(parts(j))
1419  ! parts_index(i) = 0 if nuclide i is not in network
1420  if (parts_index(j) .eq. 0) cycle fission_loop
1421  end do inner_fission
1422  end select
1423 
1424  ! Keep track for debugging
1425  if (reac_type .eq. rrt_nf) n_nf=n_nf+1 !< count neutron induced fission
1426  if (reac_type .eq. rrt_sf) n_sf=n_sf+1 !< count spontaneous fission
1427  if (reac_type .eq. rrt_bf) n_bf=n_bf+1 !< count beta delayed fission
1428 
1429  ! Set the amount of released neutrons per default to 0
1430  fissrate(fissindex)%released_n = 0
1431 
1432  if (reac_type.eq.rrt_nf) then ! neutron-induced fission
1433  fissrate(fissindex)%reac_type = reac_type
1434  fissrate(fissindex)%param = params
1435  ! Save fission nucleus index
1436  if (parts_index(1) .eq. ineu) then
1437  fissrate(fissindex)%fissnuc_index = parts_index(2)
1438  else
1439  fissrate(fissindex)%fissnuc_index = parts_index(1)
1440  end if
1441 
1442  else if (reac_type.eq.rrt_sf) then ! spontaneous fission
1443  fissrate(fissindex)%reac_type = reac_type
1444  fissrate(fissindex)%param = params
1445  ! Save fission nucleus index
1446  fissrate(fissindex)%fissnuc_index = parts_index(1)
1447 
1448  else if (reac_type.eq.rrt_bf) then ! beta-delayed fission
1449  ! Check if there should be neutrons released
1450  fissrate(fissindex)%released_n = count(parts_index(:) .eq. ineu)
1451  fissrate(fissindex)%reac_type = reac_type
1452  fissrate(fissindex)%param = params
1453  ! Save fission nucleus index
1454  fissrate(fissindex)%fissnuc_index = parts_index(1)
1455 
1456 
1457  end if
1458  fissrate(fissindex)%src = src
1459 
1460 
1461  fissindex = fissindex + 1
1462  end do fission_loop
1463 
1464  ! Return the number of fission rates that have been added
1465  start_idx = fissindex
1466 
1467  ! Close the fission file again
1468  close(fissionlib)
1469 
1470  end subroutine read_fission_rates_reaclib_format
1471 
1472 
1473 
1474  !> Read the fission rates in probability format
1475  !!
1476  !! This subroutine reads fission rates in probability format
1477  !! and stores the result in count_rates. The subroutine can be called
1478  !! for beta-delayed fission and will throw an error for other types of fission.
1479  !! An example of an entry can be:
1480  !! \file{
1481  !! pa291 mp18
1482  !! 0.000 0.008 0.000 0.015 0.000 0.018 0.000 0.025 0.000 0.003
1483  !! pa292 mp18
1484  !! 0.000 0.001 0.002 0.000 0.004 0.000 0.006 0.000 0.018 0.000
1485  !! pa293 mp18
1486  !! 0.239 0.001 0.000 0.009 0.000 0.010 0.000 0.014 0.000 0.009
1487  !! ...}
1488  !! where the first line of an entry gives nucleus name and the source. The second line
1489  !! gives the probabilities of the fission channels (i.e., P0nf, P1nf, ...).
1490  !! Note that there is a maximum number of columns (i.e., neutron emission) set to 30 here.
1491  !! Throughout the file, the amount of possible channels have to stay the same, but they
1492  !! can be different for two different files. For example, for Panov et al. 2005 the file
1493  !! could look like:
1494  !! \file{
1495  !! u259 pa05
1496  !! 0.990
1497  !! u260 pa05
1498  !! 0.020
1499  !! u261 pa05
1500  !! 0.990
1501  !! ...}.
1502  !!
1503  !! @author M. Reichert
1504  !! @date 31.05.24
1505  subroutine read_fission_rates_probability_format(fission_path,reac_type,start_idx)
1506  use benam_class, only: benam
1507  use global_class, only: isotope, ineu, net_names
1508  use error_msg_class, only: raise_exception
1510  use format_class
1511  implicit none
1512  character(len=*), intent(in) :: fission_path!< Path to fission rates file
1513  integer, intent(in) :: reac_type !< Reaction type
1514  integer, intent(inout) :: start_idx !< Start index for fission rates
1515  ! Internal variables
1516  integer :: read_stat !< Read status
1517  integer :: fissionlib !< File id of fisionrates
1518  character(5), dimension(6) :: parts !< Participating nuclei names
1519  integer, dimension(6) :: parts_index !< Participating nuclei indices
1520  real(r_kind), dimension(9) :: params !< Reaclib fitting parameter
1521  character(4) :: src !< Reaclib source label
1522  integer :: group_index !< Storage for the current chapter
1523  integer :: fissindex !< Index for current fission rate
1524  integer :: j !< Loop variable
1525  integer :: idx_parent !< Index of the parent nucleus
1526  character(5) :: parent !< Parent nucleus name
1527  real(r_kind),dimension(amount_cols):: pnf !< Probability of beta-delayed neutron emission fission
1528 
1529  ! Counter for fission rates
1530  fissindex = start_idx
1531 
1532  ! Open fission file
1533  fissionlib = open_infile(fission_path)
1534 
1535  ! Count the rates
1536  fission_prob: do
1537  ! An example entry could be: pa250 pa05
1538  ! 0.010
1539  read(fissionlib,*, iostat = read_stat) parent, src
1540  if (read_stat /= 0) exit
1541  read(fissionlib,*, iostat = read_stat) pnf
1542  ! Throw error if the file ends with a parent and a source
1543  if (read_stat /= 0) call raise_exception("Could not read fission probabilities.",&
1544  "read_fission_rates_probability_format",&
1545  190012)
1546 
1547 
1548  ! Check if the parent is included in the network
1549  idx_parent = benam(parent)
1550  if (idx_parent .eq. 0) cycle fission_prob
1551 
1552 
1553  parts_index(:) = 0
1554  parts_index(1) = idx_parent
1555 
1556  do j=1,amount_cols
1557  if (pnf(j) .eq. 0d0) cycle
1558 
1559  params(:) = 0d0
1560  params(1) = pnf(j) ! This will be changed once the reactions are merged
1561  params(2) = j-1 ! Gives the amount of released neutrons
1562 
1563  if (reac_type.eq.rrt_bf) then ! beta-delayed fission
1564  group_index = 2
1565  fissrate(fissindex)%reac_type = reac_type
1566  fissrate(fissindex)%param = params
1567  ! Save fission nucleus index
1568  fissrate(fissindex)%fissnuc_index = parts_index(1)
1569  fissrate(fissindex)%released_n = j-1
1570  else
1571  call raise_exception("Fission type not implemented for probability format!",&
1572  "read_fission_rates_probability_format",&
1573  190011)
1574  end if
1575  ! Put also the source there
1576  fissrate(fissindex)%src = src
1577 
1578  ! Also save it in a separate array that is more easier to
1579  ! access by index
1580  beta_delayed_fiss_probs(idx_parent,j) = pnf(j)
1581 
1582  ! Keep track for debugging
1583  if (reac_type .eq. rrt_bf) n_bf=n_bf+1 ! count beta delayed fission
1584 
1585  fissindex = fissindex + 1
1586  end do
1587  ! Check input
1588  if (sum(beta_delayed_fiss_probs(idx_parent,:)) .gt. 1d0) then
1589  call raise_exception("Sum of beta-delayed fission probabilities for "//net_names(idx_parent)//&
1590  " is larger than one.", "read_fission_rates_probability_format",&
1591  190017)
1592  end if
1593  end do fission_prob
1594 
1595  ! Close the fission file again
1596  close(fissionlib)
1597 
1599 
1600 
1601  !> Read fission rates in half-life format
1602  !!
1603  !! This subroutine reads fission rates in half-life format.
1604  !! The subroutine can be called for spontaneous and beta-delayed fission
1605  !! and throws an error otherwise.
1606  !! An example of an entry can be:
1607  !! \file{
1608  !! th198 4.760787e-09 kh20
1609  !! th199 2.808520e-08 kh20
1610  !! th200 2.841403e-08 kh20
1611  !! ...}
1612  !! where the first columns gives the nucleus, the second the halflife in seconds
1613  !! and the third the source. Note that in this format, no beta-delayed neutrons
1614  !! can be specified.
1615  !!
1616  !! @author M. Reichert
1617  !! @date 30.05.24
1618  subroutine read_fission_rates_halflife_format(fission_path,reac_type,start_idx)
1619  use benam_class, only: benam
1620  use global_class, only: isotope, ineu
1621  use error_msg_class, only: raise_exception
1623  use format_class
1624  implicit none
1625  character(len=*), intent(in) :: fission_path !< Path to fission rates file
1626  integer, intent(in) :: reac_type !< Reaction type
1627  integer, intent(inout) :: start_idx !< Start index for fission rates
1628  integer :: read_stat !< Read status
1629  integer :: fissionlib !< File id of fisionrates
1630  character(5), dimension(6) :: parts !< Participating nuclei names
1631  integer, dimension(6) :: parts_index !< Participating nuclei indices
1632  real(r_kind), dimension(9) :: params !< Reaclib fitting parameter
1633  character(4) :: src !< Reaclib source label
1634  integer :: group_index !< Storage for the current chapter
1635  integer :: fissindex !< Index for current fission rate
1636  integer :: j !< Loop variable
1637 
1638 
1639 
1640  !-- Open the fission library file
1641  fissionlib = open_infile(fission_path)
1642 
1643  ! make sure counting index for reaction rates continues for fission rates
1644  fissindex = start_idx
1645  fission_loop: do
1646  ! Set parts to empty strings
1647  parts(1:6) = ' '
1648  params(:) = 0d0
1649  read(fissionlib, *, iostat = read_stat) &
1650  parts(1), params(1), src
1651  if (read_stat /= 0) exit fission_loop
1652 
1653  params(1) = dlog(dlog(2d0)/params(1)) ! Convert half-life to reaclib a0
1654  parts_index = 0
1655  inner_fission: do j=1,6
1656  if (parts(j) .eq. ' ') exit inner_fission
1657  parts_index(j) = benam(parts(j))
1658  ! parts_index(i) = 0 if nuclide i is not in network
1659  if (parts_index(j) .eq. 0) cycle fission_loop
1660  end do inner_fission
1661 
1662  ! Keep track for debugging
1663  if (reac_type .eq. rrt_nf) n_nf=n_nf+1 ! count neutron induced fission
1664  if (reac_type .eq. rrt_sf) n_sf=n_sf+1 ! count spontaneous fission
1665  if (reac_type .eq. rrt_bf) n_bf=n_bf+1 ! count beta delayed fission
1666 
1667  ! Per default set number of released neutrons to zero (important for bdel fission)
1668  fissrate(fissindex)%released_n = 0
1669  if (reac_type .eq.rrt_sf) then ! spontaneous fission
1670  fissrate(fissindex)%reac_type = reac_type
1671  fissrate(fissindex)%param = params
1672  ! Save fission nucleus index
1673  fissrate(fissindex)%fissnuc_index = parts_index(1)
1674 
1675  else if (reac_type .eq. rrt_bf) then ! beta-delayed fission
1676  fissrate(fissindex)%reac_type = reac_type
1677  fissrate(fissindex)%param = params
1678  ! Save fission nucleus index
1679  fissrate(fissindex)%fissnuc_index = parts_index(1)
1680  else
1681  call raise_exception("Fission type not implemented for half life format!",&
1682  "read_fission_rates_halflife_format",&
1683  190011)
1684  end if
1685 
1686  ! Set some reaclib chapter, note that n induced fission should
1687  ! not have a halflife format
1688  group_index = 2
1689 
1690  ! Put the source to the rate
1691  fissrate(fissindex)%src = src
1692 
1693  fissindex = fissindex + 1
1694  end do fission_loop
1695 
1696  ! Return the number of fission rates that have been added
1697  start_idx = fissindex
1698 
1699  ! Close the fission file again
1700  close(fissionlib)
1701 
1702  end subroutine read_fission_rates_halflife_format
1703 
1704 
1705 
1706 
1707 
1708 
1709  !> Determines fission fragment mass distribution as described in Panov et al. 2001.
1710  !!
1711  !! This routine is called for \ref parameter_class::fissflag = 1 and fills
1712  !! the array \ref fissrates with indices of the fragment nuclei.
1713  !!
1714  !! @see [Panov et al., Nuc. Phys. A688 2001](https://ui.adsabs.harvard.edu/abs/2001NuPhA.688..587P/abstract)
1715  !! @author C. Winteler
1716  subroutine fiss_dist(fissrate_inout)
1717  use global_class, only: isotope, ineu
1718  use benam_class, only: minmax, findaz
1720  implicit none
1721  type(fissionrate_type),intent(inout) :: fissrate_inout !< Temporary fission rate
1722  ! Internal variables
1723  integer :: mass !< mass of fissioning nucleus
1724  integer :: pnr !< proton number of fissioning nucleus
1725  integer :: af,zf !< mass and proton number of "compound" nucleus
1726  integer :: a1,z1 !< mass and proton number of fragment 1
1727  integer :: a2,z2 !< mass and proton number of fragment 2
1728  integer :: nemiss !< number of fission neutrons
1729  integer :: fiss_mode !< specifies fission mode
1730  real(r_kind) :: qval !< Qvalue of fission reaction
1731  integer :: alloc_stat!< Allocation status
1732 
1733  info_entry("fiss_dist")
1734 
1735  ! Counter for additional neutrons in case of
1736  ! fragment beyond dripline.
1737  nemiss = 0
1738 
1739  ! Get the mass and proton number
1740  mass = isotope(fissrate_inout%fissnuc_index)%mass
1741  pnr = isotope(fissrate_inout%fissnuc_index)%p_nr
1742 
1743  !neutron induced fission
1744  if (fissrate_inout%reac_type .eq. rrt_nf) then
1745  fiss_mode = 1
1746  af = mass+1
1747  zf = pnr
1748  !spontaneous fission
1749  else if (fissrate_inout%reac_type .eq. rrt_sf) then
1750  fiss_mode = 2
1751  af = mass
1752  zf = pnr
1753  !beta delayed fission
1754  else if (fissrate_inout%reac_type .eq. rrt_bf) then
1755  fiss_mode = 3
1756  ! Take care of beta-delayed neutron emission fission
1757  ! The amount of neutrons is stored in the second parameter
1758  ! of the fission rate
1759  nemiss = fissrate_inout%released_n
1760  af = mass-nemiss
1761  zf = pnr + 1
1762  end if
1763 
1764  select case (af)
1765  case(255:265) ! -> symmetric fission
1766  a2 = nint(af/2.d0)
1767  z2 = nint(zf/2.d0)
1768  a1 = af - a2
1769  z1 = zf - z2
1770  case default ! -> asymmetric fission
1771  a2 = 130
1772  z2 = nint(52.01 - (zf - 80)/1.d1)
1773  ! a2 = max(a2,af-a2) !modification to prevent very n-rich
1774  ! z2 = max(z2,zf-z2) !fragments
1775  a1 = af - a2
1776  z1 = zf - z2
1777  end select
1778 
1779  if (a1.gt.minmax(z1,2)) then
1780  nemiss = nemiss + a1 - minmax(z1,2)
1781  a1 = minmax(z1,2)
1782  else if (a1.lt.minmax(z1,1)) then
1783  if (verbose_level .ge. 2) then
1784  print *, 'a1 error:', z1, a1, zf, af
1785  print *, 'adjusting...'
1786  end if
1787  a1 = minmax(z1,1)
1788  a2 = af - a1
1789  end if
1790 
1791  if (a2.gt.minmax(z2,2)) then
1792  nemiss = nemiss + a2 - minmax(z2,2)
1793  a2 = minmax(z2,2)
1794 
1795  else if (a2.lt.minmax(z2,1)) then
1796  if (verbose_level .ge. 2) then
1797  print *, 'a2 error:', z2, a2, zf, af
1798  print *, 'adjusting...'
1799  end if
1800  a2 = minmax(z2,1)
1801  a1 = af - a2
1802  end if
1803  nufiss = nufiss + nemiss
1804 
1805  fissrate_inout%fissnuc_index = findaz(mass,pnr)
1806  fissrate_inout%channels = 1
1807 
1808  allocate(fissrate_inout%channelprob(1),fissrate_inout%q_value(1),stat=alloc_stat)
1809  if (alloc_stat.ne.0) call raise_exception("Could not allocate memory for channelprob and q_value.",&
1810  "fiss_dist",190001)
1811 
1812  fissrate_inout%channelprob(1) = 1.d0
1813  fissrate_inout%mode = fiss_mode
1814 
1815  if (fiss_mode.eq.1) then
1816  fissrate_inout%dimens = 4
1817  allocate(fissrate_inout%fissparts(fissrate_inout%dimens), &
1818  fissrate_inout%ch_amount(fissrate_inout%dimens),stat=alloc_stat)
1819  if (alloc_stat.ne.0) call raise_exception("Could not allocate 'fissparts' and 'ch_amount'.",&
1820  "fiss_dist",190001)
1821  fissrate_inout%fissparts(1) = ineu
1822  fissrate_inout%ch_amount(1) = float(nemiss) - 1.d0
1823  fissrate_inout%fissparts(2) = fissrate_inout%fissnuc_index
1824  fissrate_inout%ch_amount(2) = -1.d0
1825  fissrate_inout%fissparts(3) = findaz(a1,z1)
1826  fissrate_inout%ch_amount(3) = 1.d0
1827  fissrate_inout%fissparts(4) = findaz(a2,z2)
1828  fissrate_inout%ch_amount(4) = 1.d0
1829  fissrate_inout%q_value(1) = (1-nemiss) * isotope(ineu)%mass_exc + &
1830  isotope(fissrate_inout%fissnuc_index)%mass_exc - &
1831  isotope(fissrate_inout%fissparts(3))%mass_exc - &
1832  isotope(fissrate_inout%fissparts(4))%mass_exc
1833  else ! fiss_mode 2 and 3
1834  if (nemiss .eq. 0) then ! no fission neutrons
1835  fissrate_inout%dimens = 3
1836  allocate(fissrate_inout%fissparts(fissrate_inout%dimens),&
1837  fissrate_inout%ch_amount(fissrate_inout%dimens),stat=alloc_stat)
1838  if (alloc_stat.ne.0) call raise_exception("Could not allocate 'fissparts' and 'ch_amount'.",&
1839  "fiss_dist",190001)
1840  else ! fission neutrons are produced
1841  fissrate_inout%dimens = 4
1842  allocate(fissrate_inout%fissparts(fissrate_inout%dimens),&
1843  fissrate_inout%ch_amount(fissrate_inout%dimens),stat=alloc_stat)
1844  if (alloc_stat.ne.0) call raise_exception("Could not allocate 'fissparts' and 'ch_amount'.",&
1845  "fiss_dist",190001)
1846  fissrate_inout%fissparts(4) = ineu
1847  fissrate_inout%ch_amount(4) = float(nemiss)
1848  end if
1849  fissrate_inout%fissparts(1) = fissrate_inout%fissnuc_index
1850  fissrate_inout%ch_amount(1) = -1.d0
1851  fissrate_inout%fissparts(2) = findaz(a1,z1)
1852  fissrate_inout%ch_amount(2) = 1.d0
1853  fissrate_inout%fissparts(3) = findaz(a2,z2)
1854  fissrate_inout%ch_amount(3) = 1.d0
1855 
1856  if (fissrate_inout%fissparts(2) .eq. -1) then
1857  call raise_exception("Fragment was not found in nucleus library, does your library have 'holes'? "//&
1858  "(A="//int_to_str(a1)//", Z="//int_to_str(z1)//")",&
1859  "fiss_dist",190013)
1860  end if
1861  if (fissrate_inout%fissparts(3) .eq. -1) then
1862  call raise_exception("Fragment was not found in nucleus library, does your library have 'holes'? "//&
1863  "(A="//int_to_str(a2)//", Z="//int_to_str(z2)//")",&
1864  "fiss_dist",190013)
1865  end if
1866 
1867  fissrate_inout%q_value(1) = isotope(fissrate_inout%fissparts(1))%mass_exc - &
1868  isotope(fissrate_inout%fissparts(2))%mass_exc - &
1869  isotope(fissrate_inout%fissparts(3))%mass_exc - &
1870  nemiss * isotope(ineu)%mass_exc
1871  end if
1872 
1873  qval = fissrate_inout%q_value(1)
1874  fissrate_inout%averageQ = qval
1875  info_exit("fiss_dist")
1876 
1877  return
1878 
1879  end subroutine fiss_dist
1880 
1881 
1882 
1883  !>
1884  !! Kodama-Takahashi distribution
1885  !!
1886  !! Subroutine that calculates fission fragment distribution as
1887  !! described in Kodama & Takahashi, Nuc. Phys. Sec.A, Vol. 239,
1888  !! Issue 3, p. 489-510, 1975.
1889  !!
1890  !! @see [Kodama & Takahashi 1975](https://ui.adsabs.harvard.edu/abs/1975NuPhA.239..489K/abstract)
1891  !!
1892  !! \b Edited:
1893  !! - 11.01.14
1894  !! - 05.12.17 (ME)
1895  !! - 30.05.2024 (MR): Fixed bug related to neutron emission if fragment was not in Sunet
1896  !! .
1897  !! @author C. Winteler
1898  subroutine kodtakdist(fissrate_inout)
1899  use parameter_class, only: unit
1900  use global_class, only: isotope,ineu
1901  use benam_class, only: minmax,findaz
1903  implicit none
1904  type(fissionrate_type),intent(inout) :: fissrate_inout !< Temporary fission rate
1905  ! Internal variables
1906  integer :: mass !< Mass number of parent nucleus
1907  integer :: pnr !< Proton number of parent nucleus
1908  integer :: nf !< number of fission channels
1909  integer :: fiss_mode !< Fission mode (1: n-induced, 2: spontaneous, 3: beta-delayed fission)
1910  integer :: af,zf !< mass and proton number of fissioning nucleus
1911  integer :: a,z !< mass and proton number of fragment
1912  integer :: a1,a2,z1,z2
1913  real(r_kind) :: paz,ptot
1914  real(r_kind) :: za,al,ah,cz,ca
1915  real(r_kind),parameter :: lim = 1.d-6 !< Limit for fragments to be taken into account
1916  integer :: nemiss !< Neutrons missing in case of fragment beyond dripline for one fragment
1917  integer :: alloc_stat !< Allocation status
1918  integer :: i !< Loop variable
1919  integer :: dimens !< Dimension of the parts in fission rate (amount fragments + 1)
1920  integer :: neutronflag !< Flag to check whether any fragment is beyond dripline
1921  real(r_kind) :: nemiss_total !< Total number of neutrons emitted (sum of nemiss)
1922  integer :: additional_neutrons !< Neutrons that may be emitted by beta decay
1923  real(r_kind) :: qval !< Q-value of the fission reaction
1924 
1925  info_entry("kodtakdist")
1926 
1927  ! Set neutron flag to zero
1928  neutronflag = 0
1929  additional_neutrons = 0d0
1930 
1931  ! Get the mass and proton number
1932  mass = isotope(fissrate_inout%fissnuc_index)%mass
1933  pnr = isotope(fissrate_inout%fissnuc_index)%p_nr
1934 
1935  !neutron induced fission
1936  if (fissrate_inout%reac_type .eq. rrt_nf) then
1937  fiss_mode = 1
1938  af = mass+1
1939  zf = pnr
1940  !spontaneous fission
1941  else if (fissrate_inout%reac_type .eq. rrt_sf) then
1942  fiss_mode = 2
1943  af = mass
1944  zf = pnr
1945  !beta delayed fission
1946  else if (fissrate_inout%reac_type .eq. rrt_bf) then
1947  fiss_mode = 3
1948  ! Take care of beta-delayed neutron emission fission
1949  ! The amount of neutrons is stored in the second parameter
1950  ! of the fission rate
1951  additional_neutrons = fissrate_inout%released_n
1952  af = mass-additional_neutrons
1953  zf = pnr + 1
1954  neutronflag = 1
1955  end if
1956 
1957  al = 0.85d0*af - 104.98d0
1958  ah = 0.15d0*af + 103.87d0
1959  cz = 0.8d0
1960  ca = 78.d0
1961 
1962  nf = 0
1963  ptot = 0.d0
1964 
1965  do a = 1,af
1966  za = zf*(a+0.6d0)/af
1967  do z=1,zf
1968  paz = 0.5d0*dexp(-((z-za)**2)/cz) * &
1969  ((dexp(-((a-al)**2)/ca))+(dexp(-((a-ah)**2)/ca)))/ &
1970  (unit%pi*dsqrt(cz*ca))
1971  if(paz.ge.lim) then
1972  nf = nf+1
1973  ptot = ptot + paz
1974  a1 = a
1975  z1 = z
1976  a2 = af - a1
1977  z2 = zf - z1
1978 
1979  ! check if any neutrons are emitted (needed to determine fissrate()%dimens)
1980  if (a1.gt.minmax(z1,2)) then
1981  neutronflag = 1
1982  else if (a1.lt.minmax(z1,1)) then
1983  if (verbose_level .ge. 2) then
1984  print *, 'Warning in kodtakdist, fragment was lighter than included nuclei'
1985  print *, 'Fragment was: ', a1, z1
1986  end if
1987  end if
1988 
1989  if (a2.gt.minmax(z2,2)) then
1990  neutronflag = 1
1991  else if (a2.lt.minmax(z2,1)) then
1992  if (verbose_level .ge. 2) then
1993  print *, 'Warning in kodtakdist, fragment was lighter than included nuclei'
1994  print *, 'Fragment was: ', a2, z2
1995  end if
1996  end if
1997 
1998  end if
1999  end do
2000  end do
2001 
2002  fissrate_inout%channels = nf
2003  fissrate_inout%fissnuc_index = findaz(mass,pnr)
2004  fissrate_inout%mode = fiss_mode
2005 
2006  ! Allocate and complain in case of failure
2007  allocate(fissrate_inout%channelprob(nf),fissrate_inout%q_value(nf), &
2008  stat=alloc_stat)
2009  if (alloc_stat .ne. 0) call raise_exception("Allocation of fission rate prob. arrays failed.",&
2010  "kodtakdist",190001)
2011 
2012 
2013  select case (fiss_mode)
2014  case(1)
2015  dimens = 2 * fissrate_inout%channels + 2
2016  fissrate_inout%dimens = dimens
2017  allocate(fissrate_inout%fissparts(dimens),fissrate_inout%ch_amount(dimens),&
2018  stat=alloc_stat)
2019  if (alloc_stat .ne. 0) call raise_exception("Allocation of fission rate parts failed.",&
2020  "kodtakdist",190001)
2021 
2022  fissrate_inout%fissparts(1) = ineu
2023  fissrate_inout%fissparts(2) = fissrate_inout%fissnuc_index
2024  fissrate_inout%ch_amount(2) = -1.d0
2025  case(2:)
2026  dimens = 2 * fissrate_inout%channels + 1
2027  if (neutronflag.eq.1) dimens = dimens+1
2028  fissrate_inout%dimens = dimens
2029  allocate(fissrate_inout%fissparts(dimens),fissrate_inout%ch_amount(dimens),&
2030  stat=alloc_stat)
2031  if (alloc_stat .ne. 0) call raise_exception("Allocation of fission rate parts failed.",&
2032  "kodtakdist",190001)
2033  fissrate_inout%ch_amount(1) = -1.d0
2034  fissrate_inout%fissparts(1) = fissrate_inout%fissnuc_index
2035  end select
2036 
2037  ! Keep track of total number of neutrons emitted
2038  nemiss_total = float(additional_neutrons)
2039  !---- start writing the fission rates to rrate
2040  i = 0
2041  do z = 1,zf
2042  massloop: do a = 1,af
2043  za = zf*(a+0.6d0)/af
2044  paz = 0.5d0*dexp(-((z-za)**2)/cz) * &
2045  ((dexp(-((a-al)**2)/ca))+(dexp(-((a-ah)**2)/ca)))/ &
2046  (unit%pi*dsqrt(cz*ca))
2047  if(paz.lt.lim) cycle massloop
2048  i = i+1
2049  paz = paz/ptot ! normalise probabilities to 1
2050  a1 = a
2051  z1 = z
2052  a2 = af - a1
2053  z2 = zf - z1
2054 
2055  nemiss = 0
2056 
2057  if (a1.gt.minmax(z1,2)) then
2058  nemiss = a1 - minmax(z1,2)
2059  a1 = minmax(z1,2)
2060 
2061  else if (a1.lt.minmax(z1,1)) then
2062  if (verbose_level .ge. 2) then
2063  print *, 'Warning in kodtakdist, fragment was lighter than included nuclei'
2064  print *, 'Fragment was: ', a1, z1
2065  end if
2066  end if
2067 
2068  if (a2.gt.minmax(z2,2)) then
2069  nemiss = nemiss + a2 - minmax(z2,2)
2070  a2 = minmax(z2,2)
2071  else if (a2.lt.minmax(z2,1)) then
2072  ! TODO: Maybe borrow neutrons here?
2073  if (verbose_level .ge. 2) then
2074  print *, 'Warning in kodtakdist, fragment was lighter than included nuclei'
2075  print *, 'Fragment was: ', a2, z2
2076  end if
2077  end if
2078 
2079  ! Count the total amount of neutrons emitted
2080  nemiss_total = nemiss_total+ float(nemiss)*paz
2081  ! fill in fissrate()%fissparts(); same as rrate()%parts(1:6), but with individual array sizes
2082  select case(fiss_mode)
2083  case(1)
2084  fissrate_inout%channelprob(i) = paz
2085  fissrate_inout%fissparts(i+2) = findaz(a1,z1)
2086  ! Check that the nucleus was really found!
2087  if (fissrate_inout%fissparts(i+2) .eq. -1) then
2088  call raise_exception("Fragment was not found in nucleus library, does your library have 'holes'? "//&
2089  "(A="//int_to_str(a1)//", Z="//int_to_str(z1)//")",&
2090  "kodtakdist",190013)
2091  end if
2092 
2093  fissrate_inout%ch_amount(i+2) = fissrate_inout%channelprob(i) ! rate at which fragment is produced per destroyed parent nucleus
2094  fissrate_inout%fissparts(i+2+fissrate_inout%channels) = findaz(a2,z2)
2095  ! Check that the nucleus was really found!
2096  if (fissrate_inout%fissparts(i+2+fissrate_inout%channels) .eq. -1) then
2097  call raise_exception("Fragment was not found in nucleus library, does your library have 'holes'? "//&
2098  "(A="//int_to_str(a2)//", Z="//int_to_str(z2)//")",&
2099  "kodtakdist",190013)
2100  end if
2101  fissrate_inout%ch_amount(i+2+fissrate_inout%channels) = fissrate_inout%channelprob(i)
2102  fissrate_inout%q_value(i) = isotope(fissrate_inout%fissnuc_index)%mass_exc - &
2103  (nemiss - 1) * isotope(ineu)%mass_exc - & ! (nemiss - 1) to account for one neutron that is destroyed
2104  isotope(fissrate_inout%fissparts(i+2))%mass_exc - &
2105  isotope(fissrate_inout%fissparts(i+2+fissrate_inout%channels))%mass_exc
2106  case(2:)
2107  fissrate_inout%channelprob(i) = paz
2108  fissrate_inout%fissparts(i+1) = findaz(a1,z1)
2109  ! Check that the nucleus was really found!
2110  if (fissrate_inout%fissparts(i+1) .eq. -1) then
2111  call raise_exception("Fragment was not found in nucleus library, does your library have 'holes'?",&
2112  "kodtakdist",190013)
2113  end if
2114 
2115  fissrate_inout%ch_amount(i+1) = fissrate_inout%channelprob(i) ! rate at which fragment is produced per destroyed parent nucleus
2116  fissrate_inout%fissparts(i+1+fissrate_inout%channels) = findaz(a2,z2)
2117  ! Check that the nucleus was really found!
2118  if (fissrate_inout%fissparts(i+1+fissrate_inout%channels) .eq. -1) then
2119  call raise_exception("Fragment was not found in nucleus library, does your library have 'holes'?",&
2120  "kodtakdist",190013)
2121  end if
2122 
2123  fissrate_inout%ch_amount(i+1+fissrate_inout%channels) = fissrate_inout%channelprob(i)
2124  if (neutronflag.eq.1) then
2125  fissrate_inout%fissparts(dimens) = ineu
2126  fissrate_inout%ch_amount(dimens) = real(nemiss)
2127  end if
2128  fissrate_inout%q_value(i) = isotope(fissrate_inout%fissnuc_index)%mass_exc - &
2129  nemiss * isotope(ineu)%mass_exc - &
2130  isotope(fissrate_inout%fissparts(i+1))%mass_exc - &
2131  isotope(fissrate_inout%fissparts(i+1+fissrate_inout%channels))%mass_exc
2132  end select
2133  end do massloop
2134  end do
2135 
2136  ! Set the neutrons correctly
2137  select case(fiss_mode)
2138  case(1)
2139  fissrate_inout%ch_amount(1) = nemiss_total - 1.d0
2140  case(2:)
2141  if (neutronflag.eq.1) then
2142  fissrate_inout%fissparts(dimens) = ineu
2143  fissrate_inout%ch_amount(dimens) = nemiss_total
2144  end if
2145  end select
2146 
2147  qval = 0.d0
2148  do i=1,fissrate_inout%dimens
2149  qval = qval - isotope(fissrate_inout%fissparts(i))%mass_exc*fissrate_inout%ch_amount(i) ! weighted average Q-value
2150  end do
2151  fissrate_inout%averageQ = qval
2152 
2153  nufiss = nufiss + int(nemiss_total)
2154 
2155  info_exit("kodtakdist")
2156  return
2157 
2158  end subroutine kodtakdist
2159 
2160 
2161 
2162  !> Read the fission distribution from a file
2163  !!
2164  !! The fission distribution is read from a file and stored in the
2165  !! fragment_array. The default file contains the fission distribution
2166  !! according to [Mumpower et al. (2020)](https://ui.adsabs.harvard.edu/abs/2020PhRvC.101e4607M/abstract).
2167  !! However, the format has been modified compared to the original publication.
2168  !! An example of the file looks like:
2169  !! \file{
2170  !! 93 220 574
2171  !! 0 0 0
2172  !! 019 048 1.96607e-06
2173  !! 020 048 2.24289e-05
2174  !! 020 049 1.88041e-05
2175  !! 020 050 7.65944e-06
2176  !! }
2177  !! The first line contains the Z, A and number of the fissioning nucleus.
2178  !! The next line is a dummy line. Then followed by Z, A and the yield Y(Z,A).
2179  !! Note that \f$\sum Y(Z,A) \cdot A \f$ should be the mass number of the
2180  !! parent nucleus. Furthermore, \f$\sum Y(Z,A) = 2\f$ in case 2 fragments are created.
2181  !! A large part of the subroutine deals with the problem what to do if the fragment
2182  !! is not included in the network. In case of a nucleus heavier than the ones contained in
2183  !! the network, the fragment is split into a lighter isotope plus neutrons.
2184  !! For lighter nuclei where neutrons would be necessary to create a nucleus that is in the network,
2185  !! the neutrons are "borrowed" from the heaviest fragment. This latter case should almost never happen.
2186  !! If the remapping fails for some reason, an error will be raised.
2187  !!
2188  !! @see [Mumpower et al. (2020)](https://ui.adsabs.harvard.edu/abs/2020PhRvC.101e4607M/abstract).
2189  !!
2190  !! @author M. Reichert
2191  !! @date 14.02.23
2192  subroutine read_fiss_fragment_file(file,fragment_array)
2194  use benam_class, only: findaz, minmax
2195  use error_msg_class, only: raise_exception
2196  implicit none
2197 
2198  character(len=*), intent(in) :: file !< File path to fission fragment file
2199  type(fragtype), dimension(:), allocatable, intent(out) :: fragment_array !< Array of fission fragments
2200 
2201  integer :: file_id !< Integer id of the file
2202  integer :: frag_counter !< Count the number of distributions
2203  integer :: zf !< Z fission nucleus
2204  integer :: af !< A fission nucleus
2205  integer :: nof !< Number of fragments
2206  integer :: i,j,m !< Loop variable
2207  integer :: read_stat !< Status variable
2208  integer :: astat !< Allocation status
2209  integer :: nem !< Number of emitted neutrons
2210  integer :: bn !< Number of borrowed neutrons
2211  real(r_kind) :: Ynem !< Yield of emitted neutrons
2212  real(r_kind) :: helper !< Yield of emitted neutrons
2213  integer :: mina,maxa !< Minimum and maximum A
2214 
2215 
2216  info_entry("read_fiss_fragment_file")
2217 
2218  ! Open the file
2219  file_id =open_infile(file)
2220 
2221  ! Count the number of relevant
2222  ! fragment distributions
2223  frag_counter = 0
2224  do
2225  read(file_id,*,iostat=read_stat) zf, af, nof
2226  if (read_stat .ne. 0) exit ! end of file
2227  read(file_id,*)
2228 
2229  do i=1,nof
2230  read(file_id,*)
2231  end do
2232 
2233  if (((findaz(af,zf) .ne. -1) .or. &
2234  (findaz(af-1,zf) .ne. -1) .or. &
2235  (findaz(af,zf-1) .ne. -1))) then
2236  frag_counter = frag_counter + 1
2237  end if
2238  end do
2239 
2240  ! Allocate the distribtions
2241  allocate(fragment_array(frag_counter),stat=astat)
2242  if (astat .ne. 0) then
2243  call raise_exception("Could not allocate 'fragment_array'.", &
2244  "read_fiss_fragment_file",190001)
2245  end if
2246 
2247  ! Read the file again
2248  rewind(file_id)
2249 
2250  fragloop: do i = 1,frag_counter
2251  read(file_id,*,iostat=read_stat) zf, af, nof
2252  read(file_id,*)
2253 
2254 
2255  ! Nucleus not included nor the decay of
2256  ! a nucleus in the network, nor reachable
2257  ! via a neutron capture
2258  if (.not. ((findaz(af,zf) .ne. -1) .or. &
2259  (findaz(af-1,zf) .ne. -1) .or. &
2260  (findaz(af,zf-1) .ne. -1))) then
2261  do j=1,nof
2262  read(file_id,*)
2263  end do
2264  cycle fragloop
2265  end if
2266 
2267 
2268  ! Allocate the fragments
2269  allocate(fragment_array(i)%net_idx(nof),&
2270  fragment_array(i)%Z(nof),&
2271  fragment_array(i)%A(nof),&
2272  fragment_array(i)%Y(nof),&
2273  stat=astat)
2274  if (astat .ne. 0) then
2275  call raise_exception("Could not allocate fragment properties.", &
2276  "read_fiss_fragment_file",190001)
2277  end if
2278 
2279  ! Store the properties
2280  fragment_array(i)%nr_frags = nof
2281  fragment_array(i)%Zp = zf
2282  fragment_array(i)%Ap = af
2283 
2284  ! Count the neutrons emitted
2285  nem = 0
2286  ynem = 0
2287 
2288  ! Read the fragments
2289  do j=1,nof
2290  read(file_id,*) fragment_array(i)%Z(j),fragment_array(i)%A(j),fragment_array(i)%Y(j)
2291  fragment_array(i)%net_idx(j) =findaz(fragment_array(i)%A(j),fragment_array(i)%Z(j))
2292 
2293  ! What to do when the fragment is not in the network?
2294  ! Ideally make neutrons until the fragment is in the network
2295  if (fragment_array(i)%net_idx(j) .eq. -1) then
2296  ! Tell the world that this is done
2297  if (verbose_level .ge. 2) then
2298  write(*,*) "Fragment ",fragment_array(i)%Z(j),fragment_array(i)%A(j),&
2299  " not in network. Splitting into lighter isotope and neutrons."
2300  end if
2301 
2302  mina = minmax(fragment_array(i)%Z(j),1)
2303  maxa = minmax(fragment_array(i)%Z(j),2)
2304  if (fragment_array(i)%A(j) .gt. maxa) then
2305  ! Rest goes to neutrons
2306  nem = nem + (fragment_array(i)%A(j)-maxa)
2307  ! Yield of neutrons is the amount scaled with the
2308  ! yield of the not included fragment
2309  ! Y * A should be conserved
2310  ynem = ynem + fragment_array(i)%Y(j)*(fragment_array(i)%A(j)-maxa)
2311  fragment_array(i)%Y(j) = fragment_array(i)%Y(j) ! THis stays conserved
2312  fragment_array(i)%A(j) = maxa
2313  fragment_array(i)%net_idx(j) = findaz(maxa,fragment_array(i)%Z(j))
2314  end if
2315  end if
2316  end do
2317 
2318  ! Check how many neutrons are avaiable and give it to the missing
2319  ! fragments
2320  do j=1,nof
2321  if (fragment_array(i)%net_idx(j) .eq. -1) then
2322 
2323  ! Say something if verbose
2324  if (verbose_level .ge. 2) then
2325  write(*,*) "Fission fragment Z=",fragment_array(i)%Z(j), &
2326  "A=",fragment_array(i)%A(j), &
2327  "Y=",fragment_array(i)%Y(j), &
2328  "not in network, trying to remap."
2329  end if
2330 
2331  ! Needed neutrons are:
2332  mina = minmax(fragment_array(i)%Z(j),1)
2333  bn = (mina-fragment_array(i)%A(j)) ! Amount of missing neutrons
2334 
2335  ! Borrow neutrons, take heaviest fragment that has enough
2336  ! abundance
2337  do m=nof,1,-1
2338  if ((fragment_array(i)%net_idx(m) .ne. -1) .and. &
2339  ((bn*fragment_array(i)%Y(j) / fragment_array(i)%A(m)) .lt. fragment_array(i)%Y(m))) then
2340  exit
2341  end if
2342  end do
2343 
2344  ! None found? Too bad, make an error
2345  if (m .eq. 0) then
2346  call raise_exception("Could not remap fission fragments, "// &
2347  "consider to include more nuclides in the network. "//&
2348  new_line('A')//&
2349  "Nucleus Z="//trim(int_to_str(fragment_array(i)%Z(j)))// &
2350  ", A="//trim(int_to_str(fragment_array(i)%A(j)))// &
2351  " was not included. "//new_line('A')//&
2352  "Need "//int_to_str(bn)//" neutrons.",&
2353  "read_fiss_fragment_file",&
2354  190008)
2355  end if
2356 
2357  ! Otherwise borrow the neutrons from the heavier fragment
2358  fragment_array(i)%Y(m) = fragment_array(i)%Y(m) - (bn*fragment_array(i)%Y(j) / fragment_array(i)%A(m))
2359  fragment_array(i)%Y(j) = fragment_array(i)%Y(j)
2360  ! Give the fragment a new identity
2361  fragment_array(i)%A(j) = mina
2362  fragment_array(i)%net_idx(j) = findaz(mina,fragment_array(i)%Z(j))
2363  end if
2364  end do
2365 
2366  ! Proof the yields, this should be Af!
2367  helper = ynem
2368  do j=1,nof
2369  helper = helper+fragment_array(i)%A(j)*fragment_array(i)%Y(j)
2370  end do
2371  if (abs(helper - float(fragment_array(i)%Ap)) .gt. 1e-2) then
2372  call raise_exception("Yield of fission fragments is not conserved. "// &
2373  "This happened for fragment distribution of "// &
2374  "Nucleus Z="//trim(int_to_str(fragment_array(i)%Zp))// &
2375  ", A="//trim(int_to_str(fragment_array(i)%Ap))// &
2376  ". Ensure that the sum is 2.","read_fiss_fragment_file",&
2377  190009)
2378  end if
2379 
2380  fragment_array(i)%neutrons = nem
2381  fragment_array(i)%Yn = ynem
2382  nufiss = nufiss + ynem
2383  end do fragloop
2384 
2385  ! Close the file
2386  close(file_id)
2387 
2388  info_exit("read_fiss_fragment_file")
2389 
2390  end subroutine read_fiss_fragment_file
2391 
2392 
2393  !> Fill the rates with the correct fragments
2394  !!
2395  !! This subroutine fills the rates with the correct fragments
2396  !! from [Mumpower et al. (2020)](https://ui.adsabs.harvard.edu/abs/2020PhRvC.101e4607M/abstract).
2397  !! This subroutine makes use of the fragtype struct.
2398  !! If no fragment is found, the fragment distribution is set to the
2399  !! one given by missing_frags.
2400  !! For beta-delayed fission the fissioning nucleus is the one of (Z+1, A)
2401  !! for neutron induced fission the nucleus with (Z, A+1), and for spontanous
2402  !! fission (not used within fissflag = 3) it is (Z,A).
2403  !!
2404  !! @author M. Reichert
2405  !! @date 14.02.2023
2406  subroutine file_fiss_frag(fissrate_inout,missing_frags)
2407  use global_class, only: isotope,ineu
2408  use benam_class, only: minmax,findaz
2410  implicit none
2411  type(fissionrate_type),intent(inout) :: fissrate_inout !< Temporary fission rate
2412  integer,optional, intent(in) :: missing_frags!< Distribution to use if not in the file (1:panov, 2:kodama)
2413  ! Internal variables
2414  integer :: mass !< Mass number of reacting nucleus
2415  integer :: pnr !< Proton number of reacting nucleus
2416  real(r_kind) :: qval !< Q-value of the reaction
2417  integer :: nfrac_distr !< Number of fragment distributions
2418  integer :: i !< Loop variable
2419  integer :: astat !< Allocation status variable
2420  integer :: ind_parent !< Index of reacting nucleus
2421  integer :: afiss !< A of fissioning nucleus
2422  integer :: zfiss !< Z of fissioning nucleus
2423  type(fragtype) :: fissfrags_tmp!< Temporary fragment distribution
2424  logical :: found !< Helper variable flag if the fragment
2425  ! distribution was found
2426  integer :: additional_neutrons !< Neutrons to be added for beta-delayed fission
2427  integer :: missing_frags_internal !< Internal variable for missing fragments
2428 
2429  info_entry("file_fiss_frag")
2430 
2431  ! Set the default missing fragments
2432  if (.not. present(missing_frags)) then
2433  missing_frags_internal = 0
2434  else
2435  missing_frags_internal = missing_frags
2436  end if
2437 
2438  ! Get the mass and proton number
2439  mass = isotope(fissrate_inout%fissnuc_index)%mass
2440  pnr = isotope(fissrate_inout%fissnuc_index)%p_nr
2441 
2442  ! Loop through the fission fragments
2443  if (fissrate_inout%reac_type .eq. rrt_bf) then
2444  nfrac_distr = size(fissfrags_beta_delayed)
2445  ! Set also the mode just to be sure
2446  fissrate_inout%mode = 3
2447  else if (fissrate_inout%reac_type .eq. rrt_nf) then
2448  nfrac_distr = size(fissfrags_n_induced)
2449  ! Set also the mode just to be sure
2450  fissrate_inout%mode = 1
2451  else if (fissrate_inout%reac_type .eq. rrt_sf) then
2452  nfrac_distr = size(fissfrags_spontaneous)
2453  ! Set also the mode just to be sure
2454  fissrate_inout%mode = 2
2455  end if
2456 
2457  ! Assume first that there are no additional neutrons
2458  additional_neutrons = fissrate_inout%released_n
2459 
2460 
2461 
2462  ! Check which nuclei is fissioning
2463  zfiss = pnr
2464  afiss = mass - additional_neutrons
2465 
2466  ! Z-1 for beta delayed fission
2467  if (fissrate_inout%reac_type .eq. rrt_bf) then
2468  zfiss = zfiss+1
2469  ! A+1 for neutron induced fission
2470  elseif (fissrate_inout%reac_type .eq. rrt_nf) then
2471  afiss = afiss+1
2472  end if
2473  ! Don't change anything for spontaneous fission
2474 
2475  ! Find relevant indices
2476  ind_parent = findaz(mass,pnr)
2477  fissrate_inout%fissnuc_index = ind_parent
2478  found = .false.
2479  do i=1,nfrac_distr
2480 
2481  if (fissrate_inout%reac_type .eq. rrt_bf) then
2482  fissfrags_tmp = fissfrags_beta_delayed(i)
2483  else if (fissrate_inout%reac_type .eq. rrt_nf) then
2484  fissfrags_tmp = fissfrags_n_induced(i)
2485  else if (fissrate_inout%reac_type .eq. rrt_sf) then
2486  fissfrags_tmp = fissfrags_spontaneous(i)
2487  end if
2488 
2489  if ((fissfrags_tmp%Zp .eq. zfiss) .and. (fissfrags_tmp%Ap .eq. afiss)) then
2490  found = .true.
2491  exit
2492  end if
2493  end do
2494 
2495  ! Not found, check what to do
2496  if (.not. found) then
2497 
2498  ! Raise an error when there is no alternative distribution specified
2499  if (missing_frags_internal .eq. 0) then
2500  call raise_exception("No fragment distribution found for Z="//int_to_str(zfiss)//", "//&
2501  "A="//int_to_str(afiss)//" in fragment file. Either add it to the fission fragment file or set "//&
2502  "'fission_frag_missing' to 1 (Panov et al. 2001) or 2 (Kodama & Takahashi 1975)",&
2503  "file_fiss_frag", 190016)
2504  end if
2505 
2506  ! Output this information
2507  if (verbose_level .ge.2) then
2508  write(*,*) "No fragment distribution found for Z=",zfiss,", A=",afiss
2509  if (missing_frags_internal .eq. 1) then
2510  write(*,*) "Using Panov 2001 instead."
2511  else if (missing_frags_internal .eq. 2) then
2512  write(*,*) "Using Kodama & Takahashi 1975 instead."
2513  end if
2514  end if
2515 
2516  if (missing_frags_internal .eq. 1) then
2517  ! Get panov distribution
2518  call fiss_dist(fissrate_inout)
2519  else if (missing_frags_internal .eq. 2) then
2520  ! Get kodama distribution
2521  call kodtakdist(fissrate_inout)
2522  else
2523  call raise_exception("Unknown missing fragment distribution. "//&
2524  "Got "//int_to_str(missing_frags_internal)//".",&
2525  "file_fiss_frag",190015)
2526  end if
2527  else
2528  ! Found, do mumpower
2529  if (fissrate_inout%reac_type .eq. rrt_bf) then
2530  fissfrags_tmp = fissfrags_beta_delayed(i)
2531  else if (fissrate_inout%reac_type .eq. rrt_nf) then
2532  fissfrags_tmp = fissfrags_n_induced(i)
2533  else if (fissrate_inout%reac_type .eq. rrt_sf) then
2534  fissfrags_tmp = fissfrags_spontaneous(i)
2535  end if
2536 
2537  ! Allocate the parts, the first two are the fissioning nucleus and neutrons
2538  allocate(fissrate_inout%fissparts(fissfrags_tmp%nr_frags+2),&
2539  fissrate_inout%ch_amount(fissfrags_tmp%nr_frags+2),&
2540  stat=astat)
2541  ! Complain if not possible
2542  if (astat .ne. 0) then
2543  call raise_exception("Could not allocate memory for fission fragments.",&
2544  "file_fiss_frag",190001)
2545  end if
2546 
2547  ! Set up the number of participants,
2548  ! Number of fragments + parent nucleus + neutrons
2549  fissrate_inout%dimens = fissfrags_tmp%nr_frags+2
2550 
2551  ! Use the correct order of the reacting nuclei
2552  if (.not. (fissrate_inout%reac_type .eq. rrt_nf)) then
2553  fissrate_inout%fissparts(1) = ind_parent
2554  fissrate_inout%fissparts(2) = ineu
2555  fissrate_inout%ch_amount(1) = -1d0
2556  fissrate_inout%ch_amount(2) = fissfrags_tmp%Yn+float(additional_neutrons)
2557  else
2558  fissrate_inout%fissparts(1) = ineu
2559  fissrate_inout%fissparts(2) = ind_parent
2560  fissrate_inout%ch_amount(1) = fissfrags_tmp%Yn-1d0+float(additional_neutrons)
2561  fissrate_inout%ch_amount(2) = -1d0
2562  end if
2563 
2564 
2565  do i=1,fissfrags_tmp%nr_frags
2566  fissrate_inout%fissparts(i+2) = fissfrags_tmp%net_idx(i)
2567  fissrate_inout%fissparts(i+2) = fissfrags_tmp%net_idx(i)
2568  fissrate_inout%ch_amount(i+2) = fissfrags_tmp%Y(i)
2569  end do
2570  end if
2571 
2572  ! Calculate the Q-value
2573  qval = 0.d0
2574  qvalue: do i=1,fissrate_inout%dimens
2575  qval = qval - isotope(fissrate_inout%fissparts(i))%mass_exc*fissrate_inout%ch_amount(i) ! weighted average Q-value
2576  end do qvalue
2577  fissrate_inout%averageQ = qval
2578 
2579  info_exit("file_fiss_frag")
2580 
2581  end subroutine file_fiss_frag
2582 
2583 
2584 
2585  !> Calculates the (neutron-induced) fission fragment mass distribution according to
2586  !! the ABLA07 model: Kelic, Ricciardi, & Schmidt (arXiv:0906.4193)
2587  !!
2588  !! @see [Kelic et al. 2009](https://ui.adsabs.harvard.edu/abs/2009arXiv0906.4193K/abstract)
2589  subroutine abla_nfiss(pos,mass,pnr,neutfission,qval)
2590  use global_class, only: isotope,ineu
2591  use benam_class, only: minmax,findaz
2592  use error_msg_class, only: raise_exception
2593 
2594  integer,intent(in) :: mass,pnr
2595  integer, intent(in) :: pos
2596  real(r_kind),intent(out) :: qval
2597  integer :: fmass,fpnr
2598  integer :: read_stat
2599  integer :: alloc_stat
2600  integer :: af,zf
2601  integer,dimension(:),allocatable :: a1,z1
2602  integer,dimension(:),allocatable :: a2,z2
2603  integer,intent(in) :: neutfission
2604  integer :: i,nof, nemiss
2605  integer :: dimens
2606  real(r_kind) :: nrate,npre,nafter
2607  real(r_kind),dimension(:),allocatable :: paz
2608  real(r_kind) :: psum
2609  real(r_kind) :: n_mult
2610  character(2) :: dummy
2611 
2612  info_entry("abla_nfiss")
2613 
2614  nemiss = 0
2615  do
2616  read(neutfission,"(I3,1X,I3,5X,I3)",iostat=read_stat) zf, af, nof
2617  if (read_stat /= 0) then !< this condition can happen and the code should be allowed to continue (stop -> exit)
2618  ! print*, 'fission reaction not found in abla_nfiss: ', fmass, fpnr
2619  exit ! parent nucleus not found in ABLA table -> continue with old Panov model (below, corresponds to fissflag=1 for this nucleus)
2620  endif
2621 
2622  read(neutfission,*,iostat=read_stat) nrate, npre, nafter
2623  if (read_stat /= 0) then
2624  call raise_exception("Could not read fission file.","abla_nfiss",190004)
2625  endif
2626 
2627  if ((af.eq.mass).and.(zf.eq.pnr).and.(nof.ne.0)) then
2628 
2629  n_mult = npre + nafter
2630  nemiss = int(dnint(n_mult))
2631  nufiss = nufiss + nemiss
2632 
2633  allocate(a1(nof),stat=alloc_stat)
2634  allocate(a2(nof),stat=alloc_stat)
2635  allocate(z1(nof),stat=alloc_stat)
2636  allocate(z2(nof),stat=alloc_stat)
2637  allocate(paz(nof),stat=alloc_stat)
2638 
2639  fissrate(pos)%channels = nof
2640  fissrate(pos)%fissnuc_index = findaz(af,zf)
2641  fissrate(pos)%mode = 1
2642 
2643  allocate(fissrate(pos)%channelprob(nof))
2644  allocate(fissrate(pos)%q_value(nof))
2645  dimens = 2 * fissrate(pos)%channels + 2
2646  fissrate(pos)%dimens = dimens
2647  allocate(fissrate(pos)%fissparts(dimens))
2648  allocate(fissrate(pos)%ch_amount(dimens))
2649  fissrate(pos)%fissparts(1) = ineu
2650  fissrate(pos)%ch_amount(1) = float(nemiss) - 1.d0
2651  fissrate(pos)%fissparts(2) = fissrate(pos)%fissnuc_index
2652  fissrate(pos)%ch_amount(2) = -1.d0
2653 
2654 
2655  psum = 0.d0
2656  inner: do i=1,nof
2657  read(neutfission,*,iostat=read_stat) &
2658  & a1(i),z1(i),paz(i)
2659  if (read_stat /= 0) then
2660  call raise_exception("Could not read fission file.","abla_nfiss",190004)
2661  endif
2662  ! check if fragment 1 is in the network
2663  if (a1(i).gt.minmax(z1(i),2)) then
2664  nemiss = nemiss + a1(i) - minmax(z1(i),2)
2665  a1(i) = minmax(z1(i),2)
2666  else if (a1(i).lt.minmax(z1(i),1)) then
2667  print *, 'a1 error:'
2668  end if
2669  a2(i) = mass + 1 - a1(i) - nemiss
2670  z2(i) = pnr - z1(i)
2671  psum = psum + paz(i)
2672 
2673  ! check if fragment 2 is in the network
2674  if (a2(i).gt.minmax(z2(i),2)) then
2675  nemiss = nemiss + a2(i) - minmax(z2(i),2)
2676  a2(i) = minmax(z2(i),2)
2677  else if (a2(i).lt.minmax(z2(i),1)) then
2678  print *, 'a2 error:', a2(i), z2(i), a1(i), z1(i), mass, pnr
2679  end if
2680  end do inner
2681 
2682  again: do i=1,nof
2683  paz(i) = paz(i)/psum ! normalize probabilities
2684  fissrate(pos)%channelprob(i) = paz(i)
2685 
2686  !---------rate for neutron-induced fission
2687  fissrate(pos)%fissparts(i+2) = findaz(a1(i),z1(i))
2688  fissrate(pos)%ch_amount(i+2) = fissrate(pos)%channelprob(i) ! rate at which fragment is produced per destroyed parent nucleus
2689  fissrate(pos)%fissparts(i+2+fissrate(pos)%channels) = findaz(a2(i),z2(i))
2690  fissrate(pos)%ch_amount(i+2+fissrate(pos)%channels) = fissrate(pos)%channelprob(i)
2691  fissrate(pos)%q_value(i) = (1-nemiss) * isotope(ineu)%mass_exc + & ! one neutron is destroyed, a number equal to nemiss are produced
2692  isotope(fissrate(pos)%fissnuc_index)%mass_exc - &
2693  isotope(fissrate(pos)%fissparts(i+2))%mass_exc - &
2694  isotope(fissrate(pos)%fissparts(i+2+fissrate(pos)%channels))%mass_exc
2695 
2696  end do again
2697 
2698  qval = 0.d0
2699  qvalue: do i=1,fissrate(pos)%channels
2700  qval = qval + fissrate(pos)%q_value(i)*fissrate(pos)%channelprob(i) ! weighted average Q-value
2701  end do qvalue
2702  fissrate(pos)%averageQ = qval
2703 
2704 
2705  deallocate(a1)
2706  deallocate(a2)
2707  deallocate(z1)
2708  deallocate(z2)
2709  deallocate(paz)
2710 
2711  rewind(neutfission,iostat=read_stat)
2712  if (read_stat /= 0) then
2713  call raise_exception("Could not rewind fission file.",&
2714  "abla_nfiss",190005)
2715  endif
2716  return
2717 
2718  else ! read nof lines to advance to next parent nucleus in the table
2719 
2720  do i=1,nof
2721  read(neutfission,*,iostat=read_stat) dummy
2722  if (read_stat /= 0) then
2723  call raise_exception("Could not read fission file.",&
2724  "abla_nfiss",190004)
2725  endif
2726  end do
2727 
2728  end if
2729 
2730  end do
2731 
2732  !--------old Panov model for nuclei not found in ABLA fission table---------------
2733  allocate(a1(1),stat=alloc_stat)
2734  allocate(a2(1),stat=alloc_stat)
2735  allocate(z1(1),stat=alloc_stat)
2736  allocate(z2(1),stat=alloc_stat)
2737 
2738  fmass = mass + 1
2739  fpnr = pnr
2740  select case (fmass)
2741  case(:240) ! -> symmetric fission
2742  a2(1) = nint(fmass/2.d0)
2743  z2(1) = nint(fpnr/2.d0)
2744  a1(1) = fmass - a2(1)
2745  z1(1) = fpnr - z2(1)
2746  case(255:265) ! -> symmetric fission
2747  a2(1) = nint(fmass/2.d0)
2748  z2(1) = nint(fpnr/2.d0)
2749  a1(1) = fmass - a2(1)
2750  z1(1) = fpnr - z2(1)
2751  case default ! -> asymmetric fission
2752  a2(1) = 130
2753  z2(1) = nint(52.01 - (fpnr - 80)/1.d1)
2754  ! a2 = max(a2,af-a2) !modification to prevent very n-rich
2755  ! z2 = max(z2,zf-z2) !fragments
2756  a1(1) = fmass - a2(1)
2757  z1(1) = fpnr - z2(1)
2758  end select
2759 
2760  nemiss = 0
2761 
2762  if (a1(1).gt.minmax(z1(1),2)) then
2763  nemiss = a1(1) - minmax(z1(1),2)
2764  a1(1) = minmax(z1(1),2)
2765  else if (a1(1).lt.minmax(z1(1),1)) then
2766  print *, 'a1 error:'
2767  end if
2768 
2769  if (a2(1).gt.minmax(z2(1),2)) then
2770  nemiss = nemiss + a2(1) - minmax(z2(1),2)
2771  a2(1) = minmax(z2(1),2)
2772  else if (a2(1).lt.minmax(z2(1),1)) then
2773  print *, 'a2 error:'
2774  end if
2775  nufiss = nufiss + nemiss
2776 
2777  fissrate(pos)%dimens = 4
2778  allocate(fissrate(pos)%fissparts(fissrate(pos)%dimens))
2779  allocate(fissrate(pos)%ch_amount(fissrate(pos)%dimens))
2780  allocate(fissrate(pos)%channelprob(1))
2781  allocate(fissrate(pos)%q_value(1))
2782  fissrate(pos)%channels = 1
2783  fissrate(pos)%fissnuc_index = findaz(mass,pnr)
2784  fissrate(pos)%mode = 1
2785  fissrate(pos)%channelprob(1) = 1.d0
2786 
2787  fissrate(pos)%fissparts(1) = ineu
2788  fissrate(pos)%ch_amount(1) = float(nemiss) - 1.d0
2789  fissrate(pos)%fissparts(2) = fissrate(pos)%fissnuc_index
2790  fissrate(pos)%ch_amount(2) = -1.d0
2791 
2792  fissrate(pos)%fissparts(3) = findaz(a1(1),z1(1))
2793  fissrate(pos)%ch_amount(3) = 1.d0
2794  fissrate(pos)%fissparts(4) = findaz(a2(1),z2(1))
2795  fissrate(pos)%ch_amount(4) = 1.d0
2796 
2797  fissrate(pos)%averageQ = (1-nemiss) * isotope(ineu)%mass_exc + &
2798  isotope(fissrate(pos)%fissparts(2))%mass_exc - &
2799  isotope(fissrate(pos)%fissparts(3))%mass_exc - &
2800  isotope(fissrate(pos)%fissparts(4))%mass_exc
2801 
2802  deallocate(a1)
2803  deallocate(a2)
2804  deallocate(z1)
2805  deallocate(z2)
2806 
2807 
2808  rewind(neutfission,iostat=read_stat)
2809  if (read_stat /= 0) then
2810  call raise_exception("Could not rewind fission file.",&
2811  "abla_nfiss",190005)
2812  endif
2813 
2814  info_exit("abla_nfiss")
2815 
2816  end subroutine abla_nfiss
2817 
2818 
2819  !> Calculates the (beta-delayed and spontaneous) fission fragment mass distribution according to
2820  !! the ABLA07 model: Kelic, Ricciardi, & Schmidt (arXiv:0906.4193)
2821  !!
2822  !! @see [Kelic et al. 2009](https://ui.adsabs.harvard.edu/abs/2009arXiv0906.4193K/abstract)
2823  subroutine abla_betafiss(pos,mass,pnr,betafission,qval)
2824  use global_class, only: isotope,ineu
2825  use benam_class, only: minmax,findaz
2826  use error_msg_class, only: raise_exception
2827  integer,intent(in) :: mass,pnr
2828  integer, intent(in) :: pos
2829  real(r_kind),intent(out) :: qval
2830  integer :: nemiss,fmass,fpnr
2831  integer :: read_stat
2832  integer :: alloc_stat
2833  integer :: af,zf
2834  integer,dimension(:),allocatable :: a1,z1
2835  integer,dimension(:),allocatable :: a2,z2
2836  integer,intent(in) :: betafission
2837  integer :: i,nof
2838  integer :: dimens
2839  real(r_kind) :: nrate,npre,nafter
2840  real(r_kind),dimension(:),allocatable :: paz
2841  real(r_kind) :: psum
2842  real(r_kind) :: n_mult
2843  character(2) :: dummy
2844 
2845  info_entry("abla_betafiss")
2846 
2847  nemiss = 0
2848  do
2849  read(betafission,*, iostat = read_stat) zf, af, nof
2850 
2851  if (read_stat /= 0) exit
2852  read(betafission,*,iostat=read_stat) nrate, npre, nafter
2853  if (read_stat /= 0) then
2854  call raise_exception("Could not read fission file.",&
2855  "abla_betafiss",190006)
2856  endif
2857  if ((af.eq.mass).and.(zf.eq.pnr).and.(nof.ne.0)) then
2858 
2859  n_mult = npre + nafter
2860  nemiss = int(dnint(n_mult))
2861  nufiss = nufiss + nemiss
2862 
2863  allocate(a1(nof),stat=alloc_stat)
2864  allocate(a2(nof),stat=alloc_stat)
2865  allocate(z1(nof),stat=alloc_stat)
2866  allocate(z2(nof),stat=alloc_stat)
2867  allocate(paz(nof),stat=alloc_stat)
2868 
2869  fissrate(pos)%channels = nof
2870  fissrate(pos)%fissnuc_index = findaz(mass,pnr)
2871  if (fissrate(pos)%reac_type.eq. rrt_sf) then
2872  fissrate(pos)%mode = 2 ! spontaneous fission
2873  else if (fissrate(pos)%reac_type.eq. rrt_bf) then
2874  fissrate(pos)%mode = 3 ! beta-delayed fission
2875  end if
2876 
2877  allocate(fissrate(pos)%channelprob(nof))
2878  allocate(fissrate(pos)%q_value(nof))
2879  dimens = 2 * fissrate(pos)%channels + 1
2880  if (nemiss.gt.0) dimens = dimens + 1 ! neutrons which would otherwise not be part of the reaction
2881  fissrate(pos)%dimens = dimens
2882  allocate(fissrate(pos)%fissparts(dimens))
2883  allocate(fissrate(pos)%ch_amount(dimens))
2884  fissrate(pos)%fissparts(1) = fissrate(pos)%fissnuc_index
2885  fissrate(pos)%ch_amount(1) = -1.d0
2886 
2887  if (nemiss.gt.0) then
2888  fissrate(pos)%fissparts(dimens) = ineu
2889  fissrate(pos)%ch_amount(dimens) = float(nemiss)
2890  end if
2891 
2892  psum = 0.d0
2893  inner: do i=1,nof
2894  read(betafission,"(I3,1X,I3,2X,F6.4)",iostat=read_stat) a1(i), z1(i), paz(i)
2895  if (read_stat /= 0) then
2896  call raise_exception("Could not read fission file.",&
2897  "abla_betafiss",190006)
2898  endif
2899 
2900  ! check if fragment 1 is in the network
2901  if (a1(i).gt.minmax(z1(i),2)) then
2902  nemiss = nemiss + a1(i) - minmax(z1(i),2)
2903  a1(i) = minmax(z1(i),2)
2904  else if (a1(i).lt.minmax(z1(i),1)) then
2905  print *, 'a1 error:'
2906  end if
2907 
2908  a2(i) = mass - a1(i) - nemiss
2909  z2(i) = pnr - z1(i)
2910  if (fissrate(pos)%mode.eq.3) z2(i) = z2(i) + 1 ! beta-delayed fission
2911  psum = psum + paz(i)
2912 
2913  ! check if fragment 2 is in the network
2914  if (a2(i).gt.minmax(z2(i),2)) then
2915  nemiss = nemiss + a2(i) - minmax(z2(i),2)
2916  a2(i) = minmax(z2(i),2)
2917  else if (a2(i).lt.minmax(z2(i),1)) then
2918  print *, 'a2 error:',a2(i),minmax(z2(i),1)
2919  end if
2920  end do inner
2921 
2922  again: do i=1,nof
2923  paz(i) = paz(i)/psum ! normalize probabilities
2924 
2925  fissrate(pos)%channelprob(i) = paz(i)
2926 
2927  !---------rate for spontaneous and beta-delayed fission
2928  fissrate(pos)%fissparts(i+1) = findaz(a1(i),z1(i)) ! first fragment
2929  fissrate(pos)%ch_amount(i+1) = fissrate(pos)%channelprob(i) ! rate at which fragment is produced per destroyed parent nucleus
2930  fissrate(pos)%fissparts(i+1+fissrate(pos)%channels) = findaz(a2(i),z2(i)) ! second fragment
2931  fissrate(pos)%ch_amount(i+1+fissrate(pos)%channels) = fissrate(pos)%channelprob(i)
2932  fissrate(pos)%q_value(i) = isotope(fissrate(pos)%fissnuc_index)%mass_exc - &
2933  nemiss * isotope(ineu)%mass_exc - &
2934  isotope(fissrate(pos)%fissparts(i+1))%mass_exc - &
2935  isotope(fissrate(pos)%fissparts(i+1+fissrate(pos)%channels))%mass_exc
2936  end do again
2937 
2938 
2939  qval = 0.d0
2940  qvalue: do i=1,fissrate(pos)%channels
2941  qval = qval + fissrate(pos)%q_value(i)*fissrate(pos)%channelprob(i) ! weighted average Q-value
2942  end do qvalue
2943  fissrate(pos)%averageQ = qval
2944 
2945  deallocate(a1)
2946  deallocate(a2)
2947  deallocate(z1)
2948  deallocate(z2)
2949  deallocate(paz)
2950 
2951  rewind(betafission,iostat=read_stat)
2952  if (read_stat /= 0) then
2953  call raise_exception("Could not rewind fission file.",&
2954  "abla_betafiss",190007)
2955  endif
2956  return
2957 
2958  else
2959 
2960  do i=1,nof
2961  read(betafission,*,iostat=read_stat) dummy
2962  if (read_stat /= 0) then
2963  call raise_exception("Could not read fission file.",&
2964  "abla_betafiss",190007)
2965  endif
2966  end do
2967 
2968  end if
2969 
2970  end do
2971 
2972  !--------old Panov model for nuclei not found in ABLA fission file---------------
2973  allocate(a1(1),stat=alloc_stat)
2974  allocate(a2(1),stat=alloc_stat)
2975  allocate(z1(1),stat=alloc_stat)
2976  allocate(z2(1),stat=alloc_stat)
2977 
2978  fmass = mass
2979  if (fissrate(pos)%reac_type.eq. rrt_sf) then
2980  fpnr = pnr
2981  fissrate(pos)%mode = 2 ! spontaneous fission
2982  else if (fissrate(pos)%reac_type.eq. rrt_bf) then
2983  fpnr = pnr + 1
2984  fissrate(pos)%mode = 3 ! beta-delayed fission
2985  end if
2986 
2987  select case (fmass)
2988  case(:240) ! -> symmetric fission
2989  a2(1) = nint(fmass/2.d0)
2990  z2(1) = nint(fpnr/2.d0)
2991  a1(1) = fmass - a2(1)
2992  z1(1) = fpnr - z2(1)
2993  case(255:265) ! -> symmetric fission
2994  a2(1) = nint(fmass/2.d0)
2995  z2(1) = nint(fpnr/2.d0)
2996  a1(1) = fmass - a2(1)
2997  z1(1) = fpnr - z2(1)
2998  case default ! -> asymmetric fission
2999  a2(1) = 130
3000  z2(1) = nint(52.01 - (fpnr - 80)/1.d1)
3001  ! a2 = max(a2,af-a2) !modification to prevent very n-rich
3002  ! z2 = max(z2,zf-z2) !fragments
3003  a1(1) = fmass - a2(1)
3004  z1(1) = fpnr - z2(1)
3005  end select
3006 
3007  nemiss = 0
3008 
3009  if (a1(1).gt.minmax(z1(1),2)) then
3010  nemiss = a1(1) - minmax(z1(1),2)
3011  a1(1) = minmax(z1(1),2)
3012  else if (a1(1).lt.minmax(z1(1),1)) then
3013  print *, 'a1 error:'
3014  end if
3015 
3016  if (a2(1).gt.minmax(z2(1),2)) then
3017  nemiss = nemiss + a2(1) - minmax(z2(1),2)
3018  a2(1) = minmax(z2(1),2)
3019  else if (a2(1).lt.minmax(z2(1),1)) then
3020  print *, 'a2 error:',a2(1),minmax(z2(1),1)
3021  end if
3022  nufiss = nufiss + nemiss
3023 
3024  if (nemiss .eq. 0) then
3025  fissrate(pos)%dimens = 3
3026  else
3027  fissrate(pos)%dimens = 4
3028  end if
3029 
3030  allocate(fissrate(pos)%fissparts(fissrate(pos)%dimens))
3031  allocate(fissrate(pos)%ch_amount(fissrate(pos)%dimens))
3032  allocate(fissrate(pos)%channelprob(1))
3033  allocate(fissrate(pos)%q_value(1))
3034  fissrate(pos)%channels = 1
3035  fissrate(pos)%fissnuc_index = findaz(mass,pnr)
3036  fissrate(pos)%channelprob(1) = 1.d0
3037 
3038  fissrate(pos)%fissparts(1) = fissrate(pos)%fissnuc_index
3039  fissrate(pos)%ch_amount(1) = -1.d0
3040 
3041  fissrate(pos)%fissparts(2) = findaz(a1(1),z1(1))
3042  fissrate(pos)%ch_amount(2) = 1.d0
3043  fissrate(pos)%fissparts(3) = findaz(a2(1),z2(1))
3044  fissrate(pos)%ch_amount(3) = 1.d0
3045  if (nemiss.gt.0) then
3046  fissrate(pos)%fissparts(4) = ineu
3047  fissrate(pos)%ch_amount(4) = float(nemiss)
3048  end if
3049 
3050  fissrate(pos)%averageQ = isotope(fissrate(pos)%fissparts(1))%mass_exc - &
3051  isotope(fissrate(pos)%fissparts(2))%mass_exc - &
3052  isotope(fissrate(pos)%fissparts(3))%mass_exc - &
3053  nemiss * isotope(ineu)%mass_exc
3054 
3055  deallocate(a1)
3056  deallocate(a2)
3057  deallocate(z1)
3058  deallocate(z2)
3059 
3060 
3061  rewind(betafission,iostat=read_stat)
3062  if (read_stat /= 0) then
3063  call raise_exception("Could not rewind fission file.",&
3064  "abla_betafiss",190007)
3065  endif
3066 
3067  info_exit("abla_betafiss")
3068 
3069  end subroutine abla_betafiss
3070 
3071 
3072 
3073 end module fission_rate_module
parameter_class::sfission_file
character(max_fname_len) sfission_file
Fission table for spontaneous fission.
Definition: parameter_class.f90:180
parameter_class::bfission_file
character(max_fname_len) bfission_file
Fission table for beta-delayed fission.
Definition: parameter_class.f90:178
fission_rate_module::count_fission_rates
subroutine, private count_fission_rates()
Count the amount of fission rates.
Definition: fission_rate_module.f90:765
fission_rate_module::n_bf
integer, private n_bf
Definition: fission_rate_module.f90:74
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
rrt_nf
#define rrt_nf
Definition: macros.h:78
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
fission_rate_module::beta_delayed_fiss_probs
real(r_kind), dimension(:,:), allocatable, private beta_delayed_fiss_probs
Definition: fission_rate_module.f90:41
fission_rate_module::fragtype
Definition: fission_rate_module.f90:48
fission_rate_module::nfiss_spont
integer, private nfiss_spont
Amount of spontaneous fission rates.
Definition: fission_rate_module.f90:69
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
fission_rate_module::init_fission_rates
subroutine, public init_fission_rates()
Initialize the fission reactions.
Definition: fission_rate_module.f90:99
fission_rate_module::n_sf
integer, private n_sf
Amount of individual reactions.
Definition: fission_rate_module.f90:74
parameter_class::fission_format_spontaneous
integer fission_format_spontaneous
Format of spontaneous fission rates (0: Off, 1: Reaclib, 2: Halflifes)
Definition: parameter_class.f90:164
fission_rate_module::read_fiss_fragment_file
subroutine read_fiss_fragment_file(file, fragment_array)
Definition: fission_rate_module.f90:2193
fission_rate_module::read_fission_rates_probability_format
subroutine, private read_fission_rates_probability_format(fission_path, reac_type, start_idx)
Definition: fission_rate_module.f90:1506
fission_rate_module::count_fission_rates_reaclib_format
subroutine, private count_fission_rates_reaclib_format(fission_rate_file, count_rates)
Count the amount of fission rates in reaclib format.
Definition: fission_rate_module.f90:843
rrs_reacl
#define rrs_reacl
Definition: macros.h:49
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
fission_rate_module
Module to deal with fission reactions.
Definition: fission_rate_module.f90:16
fission_rate_module::abla_betafiss
subroutine, private abla_betafiss(pos, mass, pnr, betafission, qval)
Calculates the (beta-delayed and spontaneous) fission fragment mass distribution according to the ABL...
Definition: fission_rate_module.f90:2824
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
rrs_aext
#define rrs_aext
Definition: macros.h:56
fission_rate_module::fissfrags_beta_delayed
type(fragtype), dimension(:), allocatable, private fissfrags_beta_delayed
Array storing fragment distributions of beta-delayed fission from file.
Definition: fission_rate_module.f90:61
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
fission_rate_module::count_fission_rates_halflife_format
subroutine, private count_fission_rates_halflife_format(fission_rate_file, count_rates)
Definition: fission_rate_module.f90:912
fission_rate_module::nfiss
integer, public nfiss
Amount of fission rates.
Definition: fission_rate_module.f90:68
fission_rate_module::read_fission_rates_halflife_format
subroutine, private read_fission_rates_halflife_format(fission_path, reac_type, start_idx)
Definition: fission_rate_module.f90:1619
fission_rate_module::nfiss_bdel
integer, private nfiss_bdel
Amount of beta-delayed fission rates.
Definition: fission_rate_module.f90:71
parameter_class::max_fname_len
integer, parameter, public max_fname_len
maximum length of filenames
Definition: parameter_class.f90:58
global_class::ineu
integer, public ineu
Definition: global_class.f90:94
mergesort_module::reorder_int
subroutine, public reorder_int(arr1, arr2, length)
Takes an array and an array with indices to reorder the first array.
Definition: mergesort_module.f90:932
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
format_class::my_format
character(60), dimension(100) my_format
Definition: format_class.f90:19
fission_rate_module::nufiss
integer, private nufiss
total number of fission neutrons
Definition: fission_rate_module.f90:72
tabulated_rate_module::multiply_tab_rate_by_factor
subroutine, public multiply_tab_rate_by_factor(rrate, factor)
Multiply a tabulated rate by a factor.
Definition: tabulated_rate_module.f90:212
parameter_class::fission_rates_spontaneous
character(max_fname_len) fission_rates_spontaneous
reaction library for spontaneous fission rates
Definition: parameter_class.f90:159
nucstuff_class
Module with helper functions such as rate tabulation, partition functions, and theoretical weak rates...
Definition: nucstuff_class.f90:11
benam_class::minmax
integer, dimension(:,:), allocatable minmax
TODO: add description.
Definition: benam_class.f90:14
fission_rate_module::fiss_dist
subroutine, private fiss_dist(fissrate_inout)
Determines fission fragment mass distribution as described in Panov et al. 2001.
Definition: fission_rate_module.f90:1717
rrs_wext
#define rrs_wext
Definition: macros.h:55
parameter_class::fissflag
integer fissflag
defines type of fission fragment distribution used
Definition: parameter_class.f90:86
fission_rate_module::read_binary_fission_reaction_data
subroutine, private read_binary_fission_reaction_data(path)
Read the fission reactions and fragment distributions from a binary file.
Definition: fission_rate_module.f90:292
rrs_twr
#define rrs_twr
Definition: macros.h:52
fission_rate_module::fissfrags_spontaneous
type(fragtype), dimension(:), allocatable, private fissfrags_spontaneous
Array storing fragment distributions of spontaneous fission from file.
Definition: fission_rate_module.f90:60
fission_rate_module::write_reac_verbose_out
subroutine, private write_reac_verbose_out()
Write the amount of individual reactions to the out.
Definition: fission_rate_module.f90:256
fission_rate_module::nfiss_n_ind
integer, private nfiss_n_ind
Amount of neutron induced fission rates.
Definition: fission_rate_module.f90:70
global_class::net_size
integer, public net_size
total number of isotopes (network size)
Definition: global_class.f90:93
parameter_class::unit
type(unit_type), public unit
constants and unit conversion factors
Definition: parameter_class.f90:54
rrs_nu
#define rrs_nu
Definition: macros.h:51
fission_rate_module::fissrate
type(fissionrate_type), dimension(:), allocatable, public fissrate
Array storing fission reactions.
Definition: fission_rate_module.f90:39
fission_rate_module::abla_nfiss
subroutine, private abla_nfiss(pos, mass, pnr, neutfission, qval)
Calculates the (neutron-induced) fission fragment mass distribution according to the ABLA07 model: Ke...
Definition: fission_rate_module.f90:2590
fission_rate_module::add_fission_fragments
subroutine add_fission_fragments()
Initializes the rates with fragments.
Definition: fission_rate_module.f90:1079
file_handling_class
Provide some basic file-handling routines.
Definition: file_handling_class.f90:18
parameter_class::fission_frag_n_induced
integer fission_frag_n_induced
Fragment distribution of n-induced fission rates in case of custom fragments (fissflag=4)
Definition: parameter_class.f90:166
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
fission_rate_module::kodtakdist
subroutine, private kodtakdist(fissrate_inout)
Kodama-Takahashi distribution.
Definition: fission_rate_module.f90:1899
parameter_class::fission_frag_spontaneous
integer fission_frag_spontaneous
Fragment distribution of spontaneous fission rates in case of custom fragments (fissflag=4)
Definition: parameter_class.f90:165
parameter_class::nfission_file
character(max_fname_len) nfission_file
Fission table for neutron-induced fission.
Definition: parameter_class.f90:179
fission_rate_module::modify_halflifes
subroutine, private modify_halflifes(rrate, rrate_length, fissrate_in, nfiss_in)
Modifies half lifes of beta decays to include fission.
Definition: fission_rate_module.f90:517
fission_rate_module::output_binary_fission_reaction_data
subroutine, public output_binary_fission_reaction_data(path)
Save the fission data to a unformatted binary file.
Definition: fission_rate_module.f90:388
r_kind
#define r_kind
Definition: macros.h:46
tabulated_rate_module::tabulated_index
subroutine, public tabulated_index(temp)
Set tab_index for a given temperature.
Definition: tabulated_rate_module.f90:537
fission_rate_module::fiss_binary_name
character(len= *), parameter, private fiss_binary_name
Name of the binary file containing the fission rates.
Definition: fission_rate_module.f90:45
parameter_class::fission_format_beta_delayed
integer fission_format_beta_delayed
Format of beta-delayed fission rates (0: Off, 1: Reaclib, 2: Halflifes, 3: Probability)
Definition: parameter_class.f90:162
fission_rate_module::fissfrags_n_induced
type(fragtype), dimension(:), allocatable, private fissfrags_n_induced
Array storing fragment distributions of neutron-induced fission from file.
Definition: fission_rate_module.f90:59
fission_rate_module::fissionrate_type
fission rate type, designed to save fragment distribution at initialization
Definition: fission_rate_module.f90:21
fission_rate_module::fiss_neglect
integer, parameter, public fiss_neglect
Amount of fission fragments not to be neglected.
Definition: fission_rate_module.f90:66
fission_rate_module::n_nf
integer, private n_nf
Definition: fission_rate_module.f90:74
rrt_betm
#define rrt_betm
Definition: macros.h:59
nucstuff_class::get_nr_reactants
integer function get_nr_reactants(group)
Get number of reactants of the reaction based on the reaclib chapter.
Definition: nucstuff_class.f90:301
parameter_class::fission_rates_n_induced
character(max_fname_len) fission_rates_n_induced
reaction library for neutron induced fission rates
Definition: parameter_class.f90:160
rrs_fiss
#define rrs_fiss
Definition: macros.h:54
file_handling_class::open_infile
integer function, public open_infile(file_name)
Same for reading (input file)
Definition: file_handling_class.f90:126
tabulated_rate_module
This module contains everything for the tabulated rates that can replace reaclib rates.
Definition: tabulated_rate_module.f90:28
fission_rate_module::reorder_fragments
subroutine, private reorder_fragments()
Reorder the fission fragments.
Definition: fission_rate_module.f90:220
global_class
Contains types and objects shared between multiple modules.
Definition: global_class.f90:19
fission_rate_module::file_fiss_frag
subroutine file_fiss_frag(fissrate_inout, missing_frags)
Fill the rates with the correct fragments.
Definition: fission_rate_module.f90:2407
parameter_class::fission_format_n_induced
integer fission_format_n_induced
Format of neutron-induced fission rates (0: Off, 1: Reaclib)
Definition: parameter_class.f90:163
tabulated_rate_module::calculate_tab_rate
subroutine, public calculate_tab_rate(rrate, temp, rat_calc)
Calculates the tabulated rate.
Definition: tabulated_rate_module.f90:191
fission_rate_module::merge_fission_rates
subroutine, public merge_fission_rates(rrate_array, rrate_length, fiss_count)
Merge fission rates with larger array.
Definition: fission_rate_module.f90:460
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
rrt_bf
#define rrt_bf
Definition: macros.h:79
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
rrt_sf
#define rrt_sf
Definition: macros.h:80
format_class
Define custom format statements used to read in major data files.
Definition: format_class.f90:16
fission_rate_module::count_fission_rates_probability_format
subroutine, private count_fission_rates_probability_format(fission_rate_file, count_rates, nr_cols)
Definition: fission_rate_module.f90:995
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
rrs_detb
#define rrs_detb
Definition: macros.h:53
parameter_class::fission_frag_missing
integer fission_frag_missing
Fragment distribution in case of missing fragments in case of custom fragments (fissflag=4)
Definition: parameter_class.f90:168
mergesort_module::bubblesort
subroutine, public bubblesort(mode, length, arr1, arr2)
Bubblesort of array.
Definition: mergesort_module.f90:724
mergesort_module
Module mergesort_module for merging arrays of rates.
Definition: mergesort_module.f90:16
fission_rate_module::read_fission_rates
subroutine, private read_fission_rates()
Read the fission rates, splitted into different types of fission.
Definition: fission_rate_module.f90:1280
parameter_class::prepared_network_path
character(max_fname_len) prepared_network_path
Prepared network folder.
Definition: parameter_class.f90:201
rrs_tabl
#define rrs_tabl
Definition: macros.h:50
fission_rate_module::read_fission_rates_reaclib_format
subroutine, private read_fission_rates_reaclib_format(fission_path, reac_type, start_idx)
Definition: fission_rate_module.f90:1372
parameter_class::fission_rates_beta_delayed
character(max_fname_len) fission_rates_beta_delayed
reaction library for beta delayed fission rates
Definition: parameter_class.f90:161
fission_rate_module::amount_cols
integer, private amount_cols
Amount of columns in the beta-delayed fission file.
Definition: fission_rate_module.f90:42
parameter_class
Contains all runtime parameters as well as phys and math constants.
Definition: parameter_class.f90:24
parameter_class::fission_frag_beta_delayed
integer fission_frag_beta_delayed
Fragment distribution of beta-delayed fission rates in case of custom fragments (fissflag=4)
Definition: parameter_class.f90:167
fission_rate_module::check_fission_mass_conservation
subroutine check_fission_mass_conservation
Check the mass conservation during the fission process.
Definition: fission_rate_module.f90:155
benam_class
Subroutines needed to initialise the network.
Definition: benam_class.f90:11