Line data Source code
1 : ! ***********************************************************************
2 : !
3 : ! Copyright (C) 2010-2019 The MESA Team
4 : !
5 : ! This program is free software: you can redistribute it and/or modify
6 : ! it under the terms of the GNU Lesser General Public License
7 : ! as published by the Free Software Foundation,
8 : ! either version 3 of the License, or (at your option) any later version.
9 : !
10 : ! This program is distributed in the hope that it will be useful,
11 : ! but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 : ! See the GNU Lesser General Public License for more details.
14 : !
15 : ! You should have received a copy of the GNU Lesser General Public License
16 : ! along with this program. If not, see <https://www.gnu.org/licenses/>.
17 : !
18 : ! ***********************************************************************
19 :
20 : module rates_initialize
21 : use const_def, only: dp, mesa_data_dir, ln2
22 : use math_lib
23 : use rates_def
24 :
25 : implicit none
26 :
27 : contains
28 :
29 10 : subroutine finish_rates_def_init
30 : use utils_lib, only: integer_dict_define, integer_dict_create_hash, integer_dict_size
31 : use reaclib_input, only: do_extract_rates
32 : use chem_def, only: nuclide_set, chem_isos, num_chem_isos, iso_name_length
33 : use chem_lib, only: generate_nuclide_set
34 : integer :: ierr
35 : character(len=iso_name_length), pointer :: names(:) =>null()
36 : type(nuclide_set), pointer :: set(:) =>null()
37 : integer, pointer :: chem_id(:) =>null()
38 : ! will be allocated by extract_nuclides_from_chem_isos
39 : logical :: use_weaklib
40 : include 'formats'
41 :
42 : ierr = 0
43 5 : call integer_dict_create_hash(reaction_names_dict, ierr)
44 5 : if (ierr /= 0) then
45 0 : write(*,*) 'FATAL ERROR: rates_def_init failed in integer_dict_create_hash'
46 0 : return
47 : end if
48 :
49 : ! set up reaclib info
50 5 : allocate(set(num_chem_isos))
51 :
52 5 : call generate_nuclide_set(chem_isos% name, set)
53 :
54 5 : use_weaklib = .true.
55 5 : call do_extract_rates(set, chem_isos, reaclib_rates, use_weaklib, ierr)
56 5 : deallocate(set)
57 5 : if (ierr /= 0) then
58 0 : write(*,*) 'FATAL ERROR: extract_reaclib_rates failed in rates_def_init'
59 0 : return
60 : end if
61 :
62 15 : end subroutine finish_rates_def_init
63 :
64 :
65 0 : subroutine do_add_reaction_for_handle(reaction_handle, ierr)
66 5 : use reaclib_support, only: do_parse_reaction_handle
67 : character (len=*), intent(in) :: reaction_handle ! to be added
68 : integer, intent(out) :: ierr
69 :
70 : integer :: ir, num_in, num_out
71 : integer :: particles_in, particles_out
72 : logical :: already_defined
73 : integer :: iso_ids(max_num_reaction_inputs+max_num_reaction_outputs)
74 : integer :: cin(max_num_reaction_inputs), cout(max_num_reaction_outputs)
75 : character (len=16) :: op ! e.g., 'pg', 'wk', 'to', or ...
76 :
77 : logical, parameter :: weak = .false.
78 : logical, parameter :: dbg = .false.
79 :
80 : include 'formats'
81 :
82 : ierr = 0
83 :
84 : if (dbg) write(*,*) 'do_add_reaction_for_handle ' // trim(reaction_handle)
85 :
86 : call do_parse_reaction_handle( &
87 0 : reaction_handle, particles_in, particles_out, iso_ids, op, ierr)
88 0 : if (ierr /= 0) then
89 : write(*,'(a)') 'add_reaction_for_handle failed in reaclib_parse_handle ' // &
90 0 : trim(reaction_handle)
91 0 : return
92 : end if
93 :
94 0 : call alloc_reaction_ir(reaction_handle, ir, already_defined, ierr)
95 0 : if (already_defined) return
96 0 : if (ierr /= 0) return
97 :
98 0 : reaction_inputs(:,ir) = 0
99 0 : reaction_outputs(:,ir) = 0
100 :
101 0 : cin(:) = 1
102 0 : cout(:) = 1
103 :
104 0 : call setup(reaction_inputs(:,ir), num_in, cin, 0, particles_in)
105 0 : call setup(reaction_outputs(:,ir), num_out, cout, particles_in, particles_out)
106 :
107 : call set_reaction_info( &
108 0 : ir, num_in, num_out, particles_in, particles_out, weak, reaction_handle, ierr)
109 0 : if (ierr /= 0) then
110 0 : write(*,*) 'failed in set_reaction_info for ' // trim(reaction_handle), ir
111 : end if
112 :
113 0 : if (dbg) write(*,*) 'done do_add_reaction_for_handle ' // trim(reaction_handle)
114 :
115 :
116 : contains
117 :
118 :
119 0 : subroutine setup(reaction_io, num, cnt, k, num_particles)
120 : integer :: reaction_io(:), num, cnt(:), k, num_particles
121 : integer :: j
122 0 : reaction_io(1) = 1
123 0 : reaction_io(2) = iso_ids(k+1)
124 0 : num = 1
125 0 : cnt(num) = 1
126 0 : do j=2,num_particles
127 0 : if (iso_ids(k+j) == iso_ids(k+j-1)) then
128 0 : cnt(num) = cnt(num) + 1
129 : else
130 0 : num = num + 1
131 0 : reaction_io(2*num) = iso_ids(k+j)
132 0 : cnt(num) = 1
133 : end if
134 0 : reaction_io(2*num-1) = cnt(num)
135 : end do
136 0 : end subroutine setup
137 :
138 :
139 : end subroutine do_add_reaction_for_handle
140 :
141 :
142 54 : subroutine do_add_reaction_from_reaclib(reaction_handle, reverse_handle, indx, ierr)
143 :
144 : character (len=*), intent(in) :: reaction_handle ! to be added
145 : character (len=*), intent(in) :: reverse_handle ! = '' if not a reverse
146 : integer, intent(in) :: indx ! index in reaclib rates
147 : integer, intent(out) :: ierr
148 :
149 : integer :: i, ir, chapter, num_in, num_out
150 : integer :: particles_in, particles_out
151 : logical :: weak, reverse, already_defined
152 : integer :: cin(max_num_reaction_inputs), cout(max_num_reaction_outputs)
153 : type (reaction_data), pointer :: r =>null()
154 :
155 : logical, parameter :: dbg = .false.
156 :
157 : include 'formats'
158 :
159 18 : ierr = 0
160 18 : i = indx
161 18 : reverse = (len_trim(reverse_handle) > 0)
162 18 : r => reaclib_rates
163 :
164 72 : cin(:) = 1
165 90 : cout(:) = 1
166 :
167 : if (dbg) write(*,'(a, 2x, i5)') 'do_add_reaction_from_reaclib ' // trim(reaction_handle), i
168 :
169 18 : if (reverse) then
170 2 : if (reverse_handle /= r% reaction_handle(i)) then
171 0 : write(*,'(a)') trim(reverse_handle) // ' ' // trim(r% reaction_handle(i))
172 0 : write(*,'(a,3x,i8)') 'bad reverse_handle for add_reaction_from_reaclib', indx
173 0 : ierr = -1
174 0 : return
175 : end if
176 : else
177 16 : if (reaction_handle /= r% reaction_handle(i)) then
178 0 : write(*,'(a)') trim(reaction_handle) // ' ' // trim(r% reaction_handle(i))
179 0 : write(*,'(a,3x,i8)') 'bad reaction_handle for add_reaction_from_reaclib', indx
180 0 : ierr = -1
181 0 : return
182 : end if
183 : end if
184 :
185 18 : chapter = r% chapter(i)
186 18 : weak = (adjustl(r% reaction_flag(i)) == 'w')
187 :
188 18 : call alloc_reaction_ir(reaction_handle, ir, already_defined, ierr)
189 18 : if (already_defined) return
190 18 : if (ierr /= 0) return
191 :
192 126 : reaction_inputs(:,ir) = 0
193 162 : reaction_outputs(:,ir) = 0
194 :
195 18 : if (.not. reverse) then
196 16 : particles_in = Nin(chapter)
197 16 : particles_out = Nout(chapter)
198 16 : call setup(reaction_inputs(:,ir), num_in, cin, 0, particles_in)
199 16 : call setup(reaction_outputs(:,ir), num_out, cout, particles_in, particles_out)
200 : else
201 2 : particles_out = Nin(chapter)
202 2 : particles_in = Nout(chapter)
203 2 : call setup(reaction_inputs(:,ir), num_in, cin, particles_out, particles_in)
204 2 : call setup(reaction_outputs(:,ir), num_out, cout, 0, particles_out)
205 : end if
206 :
207 : call set_reaction_info( &
208 18 : ir, num_in, num_out, particles_in, particles_out, weak, reaction_handle, ierr)
209 18 : if (ierr /= 0) then
210 0 : write(*,*) 'failed in set_reaction_info for ' // trim(reaction_handle), ir
211 : end if
212 :
213 : if (dbg) write(*,*) 'done do_add_reaction_from_reaclib'
214 :
215 :
216 : contains
217 :
218 :
219 36 : subroutine setup(reaction_test, num, cnt, k, num_particles)
220 : integer :: reaction_test(:), num, cnt(:), k, num_particles
221 : integer :: j
222 36 : reaction_test(1) = 1
223 36 : reaction_test(2) = r% pspecies(k+1,i)
224 36 : num = 1
225 36 : cnt(num) = 1
226 40 : do j=2,num_particles
227 4 : if (r% pspecies(k+j,i) == r% pspecies(k+j-1,i)) then
228 0 : cnt(num) = cnt(num) + 1
229 : else
230 4 : num = num + 1
231 4 : reaction_test(2*num) = r% pspecies(k+j,i)
232 4 : cnt(num) = 1
233 : end if
234 40 : reaction_test(2*num-1) = cnt(num)
235 : end do
236 36 : end subroutine setup
237 :
238 :
239 : end subroutine do_add_reaction_from_reaclib
240 :
241 :
242 18 : subroutine alloc_reaction_ir(reaction_handle, ir, already_defined, ierr)
243 : character (len=*), intent(in) :: reaction_handle
244 : integer, intent(out) :: ir
245 : logical, intent(out) :: already_defined
246 : integer, intent(out) :: ierr
247 : logical, parameter :: dbg = .false.
248 : include 'formats'
249 18 : ierr = 0
250 18 : ir = get_rates_reaction_id(reaction_handle)
251 18 : if (ir > 0) then
252 0 : already_defined = .true.
253 0 : return
254 : end if
255 18 : !$omp critical (lock_alloc_reaction_ir)
256 18 : ir = get_rates_reaction_id(reaction_handle)
257 18 : if (ir > 0) then
258 0 : already_defined = .true.
259 : else
260 18 : already_defined = .false.
261 : if (dbg) write(*,2) 'call increase_num_reactions', rates_reaction_id_max
262 18 : call increase_num_reactions(ierr)
263 18 : if (ierr == 0) then
264 18 : ir = rates_reaction_id_max
265 : if (dbg) write(*,2) 'after increase_num_reactions', rates_reaction_id_max
266 : end if
267 : end if
268 : !$omp end critical (lock_alloc_reaction_ir)
269 : end subroutine alloc_reaction_ir
270 :
271 :
272 18 : subroutine set_reaction_info( &
273 : ir, num_in, num_out, particles_in, particles_out, weak, reaction_handle, ierr)
274 : use chem_def
275 : use utils_lib, only: integer_dict_define
276 : integer, intent(in) :: ir, num_in, num_out, particles_in, particles_out
277 : logical, intent(in) :: weak
278 : character (len=*), intent(in) :: reaction_handle
279 : integer, intent(out) :: ierr
280 :
281 : integer :: j, iso_in, iso_out, weak_j, cin1
282 :
283 : logical, parameter :: dbg = .false.
284 :
285 : include 'formats'
286 :
287 18 : ierr = 0
288 :
289 18 : reaction_Name(ir) = reaction_handle
290 :
291 : if (dbg) write(*,*) 'call get_Qtotal'
292 18 : std_reaction_Qs(ir) = get_Qtotal(ir)
293 18 : std_reaction_neuQs(ir) = 0d0
294 18 : weak_lowT_rate(ir) = -1d99
295 :
296 18 : iso_in = reaction_inputs(num_in*2,ir)
297 18 : cin1 = reaction_inputs(num_in*2-1,ir)
298 18 : iso_out = reaction_outputs(num_out*2,ir)
299 :
300 18 : if (iso_in < 0 .or. iso_in > num_chem_isos) then
301 0 : write(*,3) 'bad iso_in', iso_in, num_in
302 0 : write(*,*) trim(reaction_handle)
303 0 : do j = 1, num_in
304 0 : write(*,3) 'reaction input', j, reaction_inputs(2*j,ir)
305 : end do
306 0 : call mesa_error(__FILE__,__LINE__,'set_reaction_info')
307 : end if
308 :
309 18 : if (iso_out < 0 .or. iso_out > num_chem_isos) then
310 0 : write(*,2) 'bad iso_out', iso_out
311 0 : write(*,2) 'num_out', num_out
312 0 : write(*,2) 'num_in', num_in
313 0 : write(*,*) trim(reaction_handle)
314 0 : do j = 1, num_out
315 0 : write(*,3) 'reaction output', j, reaction_outputs(2*j,ir)
316 : end do
317 0 : call mesa_error(__FILE__,__LINE__,'set_reaction_info')
318 : end if
319 :
320 18 : if (weak) then
321 14 : weak_reaction_info(1,ir) = iso_in
322 14 : weak_reaction_info(2,ir) = iso_out
323 14 : weak_j = do_get_weak_info_list_id(chem_isos% name(iso_in),chem_isos% name(iso_out))
324 14 : if (weak_j > 0) std_reaction_neuQs(ir) = weak_info_list_Qneu(weak_j)
325 14 : call set_weak_lowT_rate(ir, ierr)
326 14 : if (ierr /= 0) return
327 : else
328 12 : weak_reaction_info(1:2,ir) = 0
329 : end if
330 :
331 18 : reaction_ye_rho_exponents(1,ir) = 0 ! 1 for electron captures, 0 for rest.
332 :
333 18 : if (particles_in > 1) then
334 2 : reaction_screening_info(1,ir) = reaction_inputs(2,ir)
335 2 : if (cin1 > 1) then
336 0 : reaction_screening_info(2,ir) = reaction_screening_info(1,ir)
337 : else
338 2 : reaction_screening_info(2,ir) = reaction_inputs(4,ir)
339 : end if
340 2 : reaction_ye_rho_exponents(2,ir) = particles_in - 1
341 : else
342 48 : reaction_screening_info(1:2,ir) = 0
343 16 : reaction_ye_rho_exponents(2,ir) = 0
344 : end if
345 18 : reaction_screening_info(3,ir) = 0
346 18 : reaction_categories(ir) = iother
347 18 : if (is_pp_reaction(reaction_handle)) then
348 0 : reaction_categories(ir) = ipp
349 18 : else if (is_cno_reaction(reaction_handle)) then
350 12 : reaction_categories(ir) = icno
351 6 : else if (num_in == 1 .and. cin1 == 2) then
352 0 : if (iso_in == ic12) then
353 0 : reaction_categories(ir) = icc
354 0 : else if (iso_in == io16) then
355 0 : reaction_categories(ir) = ioo
356 : end if
357 6 : else if (num_in > 1) then
358 2 : select case(chem_isos% Z(iso_in))
359 : case (6)
360 0 : reaction_categories(ir) = i_burn_c
361 : case (7)
362 0 : reaction_categories(ir) = i_burn_n
363 : case (8)
364 0 : reaction_categories(ir) = i_burn_o
365 : case (10)
366 2 : reaction_categories(ir) = i_burn_ne
367 : case (11)
368 0 : reaction_categories(ir) = i_burn_na
369 : case (12)
370 0 : reaction_categories(ir) = i_burn_mg
371 : case (14)
372 0 : reaction_categories(ir) = i_burn_si
373 : case (16)
374 0 : reaction_categories(ir) = i_burn_s
375 : case (18)
376 0 : reaction_categories(ir) = i_burn_ar
377 : case (20)
378 0 : reaction_categories(ir) = i_burn_ca
379 : case (22)
380 0 : reaction_categories(ir) = i_burn_ti
381 : case (24)
382 0 : reaction_categories(ir) = i_burn_cr
383 : case (26)
384 2 : reaction_categories(ir) = i_burn_fe
385 : end select
386 4 : else if (particles_in == 1 .and. particles_out == 2 .and. .not. weak) then
387 2 : reaction_categories(ir) = iphoto
388 : end if
389 :
390 18 : reaction_Info(ir) = reaction_handle
391 :
392 : if (dbg) write(*,'(a,3x,i5)') 'call integer_dict_define ' // trim(reaction_handle), ir
393 :
394 18 : call integer_dict_define(reaction_names_dict, reaction_handle, ir, ierr)
395 18 : if (ierr /= 0) then
396 0 : write(*,*) 'FATAL ERROR: set_reaction_info failed in integer_dict_define'
397 0 : return
398 : end if
399 :
400 36 : end subroutine set_reaction_info
401 :
402 :
403 214 : subroutine set_weak_lowT_rate(ir, ierr)
404 18 : use chem_def
405 : use utils_lib, only: integer_dict_define
406 : use reaclib_eval, only: do_reaclib_indices_for_reaction
407 : use ratelib, only: reaclib_rate_and_dlnT
408 : use load_weak, only: do_get_weak_rate_id
409 :
410 : integer, intent(in) :: ir
411 : integer, intent(out) :: ierr
412 : integer :: i, lo, hi, weak_reaclib_id_i
413 214 : real(dp) :: half_life, lambda, dlambda_dlnT, rlambda, drlambda_dlnT
414 :
415 : include 'formats'
416 :
417 214 : weak_reaclib_id_i = 0
418 :
419 214 : if (weak_reaction_info(1,ir) == 0 .or. weak_reaction_info(2,ir) == 0) return
420 :
421 : call do_reaclib_indices_for_reaction( &
422 209 : reaction_Name(ir), reaclib_rates, lo, hi, ierr)
423 209 : if (ierr /= 0) then ! not in reaclib
424 195 : ierr = 0
425 : i = do_get_weak_info_list_id( &
426 : chem_isos% name(weak_reaction_info(1,ir)), &
427 195 : chem_isos% name(weak_reaction_info(2,ir)))
428 195 : if (i > 0) then
429 20 : half_life = weak_info_list_halflife(i)
430 20 : if (half_life > 0d0) then
431 20 : weak_lowT_rate(ir) = ln2/half_life
432 20 : return
433 : end if
434 : end if
435 175 : weak_lowT_rate(ir) = -1d-99
436 175 : return
437 : end if
438 :
439 : ! evaluate rates at T= 10^7 K (i.e. T9 = 0.01)
440 : call reaclib_rate_and_dlnT( &
441 : lo, hi, reaction_Name(ir), 0.01_dp, &
442 14 : lambda, dlambda_dlnT, rlambda, drlambda_dlnT, ierr)
443 14 : if (ierr /= 0) then
444 : write(*,2) 'set_reaction_info failed in reaclib_rate_and_dlnT ' // &
445 0 : trim(reaction_Name(ir)), ir
446 0 : call mesa_error(__FILE__,__LINE__)
447 : end if
448 14 : if (lo <= reaclib_rates% num_from_weaklib) then
449 8 : if (.not. reaclib_rates% also_in_reaclib(lo)) lambda = -1
450 : end if
451 14 : weak_lowT_rate(ir) = lambda
452 :
453 : weak_reaclib_id_i = do_get_weak_rate_id( &
454 : chem_isos% name(weak_reaction_info(1,ir)), &
455 14 : chem_isos% name(weak_reaction_info(2,ir)))
456 14 : if (weak_reaclib_id_i == 0) return
457 8 : weak_reaclib_id(weak_reaclib_id_i) = ir
458 :
459 214 : end subroutine set_weak_lowT_rate
460 :
461 :
462 18 : logical function is_pp_reaction(reaction_handle)
463 : character (len=*), intent(in) :: reaction_handle
464 : is_pp_reaction = &
465 : reaction_handle == 'r_h1_h1_wk_h2' .or. &
466 : reaction_handle == 'r_h1_h1_ec_h2' .or. &
467 : reaction_handle == 'r_h2_pg_he3' .or. &
468 : reaction_handle == 'r_he3_he3_to_h1_h1_he4' .or. &
469 : reaction_handle == 'r_he3_ag_be7' .or. &
470 : reaction_handle == 'r_be7_wk_li7' .or. &
471 : reaction_handle == 'r_h1_li7_to_he4_he4' .or. &
472 : reaction_handle == 'r_li7_pa_he4' .or. &
473 : reaction_handle == 'r_be7_pg_b8' .or. &
474 18 : reaction_handle == 'r_b8_wk_he4_he4'
475 214 : end function is_pp_reaction
476 :
477 :
478 18 : logical function is_cno_reaction(reaction_handle)
479 : character (len=*), intent(in) :: reaction_handle
480 : is_cno_reaction = &
481 : reaction_handle == 'r_c12_pg_n13' .or. &
482 : reaction_handle == 'r_c13_pg_n14' .or. &
483 : reaction_handle == 'r_n13_wk_c13' .or. &
484 : reaction_handle == 'r_n13_pg_o14' .or. &
485 : reaction_handle == 'r_n14_pg_o15' .or. &
486 : reaction_handle == 'r_n15_pg_o16' .or. &
487 : reaction_handle == 'r_n15_pa_c12' .or. &
488 : reaction_handle == 'r_o14_wk_n14' .or. &
489 : reaction_handle == 'r_o14_ap_f17' .or. &
490 : reaction_handle == 'r_o15_wk_n15' .or. &
491 : reaction_handle == 'r_o16_pg_f17' .or. &
492 : reaction_handle == 'r_o17_pg_f18' .or. &
493 : reaction_handle == 'r_o17_pa_n14' .or. &
494 : reaction_handle == 'r_o18_pg_f19' .or. &
495 : reaction_handle == 'r_o18_pa_n15' .or. &
496 : reaction_handle == 'r_f17_wk_o17' .or. &
497 : reaction_handle == 'r_f17_pg_ne18' .or. &
498 : reaction_handle == 'r_f18_pa_o15' .or. &
499 : reaction_handle == 'r_f18_wk_o18' .or. &
500 : reaction_handle == 'r_f19_pa_o16' .or. &
501 18 : reaction_handle == 'r_ne18_wk_f18'
502 18 : end function is_cno_reaction
503 :
504 :
505 3 : subroutine free_raw_rates_records
506 : type (rate_table_info), pointer :: ri =>null()
507 : integer :: i
508 3 : if (ASSOCIATED(raw_rates_records)) then
509 954 : do i = 1, rates_reaction_id_max
510 951 : ri => raw_rates_records(i)
511 951 : if (ASSOCIATED(ri% T8s)) deallocate(ri% T8s)
512 954 : if (ASSOCIATED(ri% f1)) deallocate(ri% f1)
513 : end do
514 3 : deallocate(raw_rates_records)
515 : end if
516 3 : end subroutine free_raw_rates_records
517 :
518 :
519 21 : subroutine init_raw_rates_records(ierr)
520 : use utils_lib
521 : use utils_def
522 : integer, intent(out) :: ierr
523 :
524 : type (rate_table_info), pointer :: ri =>null()
525 : integer :: i, iounit, n, t
526 : character (len=256) :: dir, rate_name, rate_fname, filename
527 : character (len=256) :: buffer
528 : logical :: okay
529 :
530 : logical, parameter :: dbg = .false.
531 :
532 : include 'formats'
533 :
534 : if (dbg) write(*,*) 'init_raw_rates_records'
535 :
536 21 : ierr = 0
537 :
538 : ! first try local rate_tables_dir
539 21 : dir = rates_table_dir
540 21 : filename = trim(dir) // '/rate_list.txt'
541 21 : open(newunit=iounit, file=trim(filename), action='read', status='old', iostat=ierr)
542 21 : if (ierr /= 0) then ! if don't find that file, look in rates_dir
543 3 : dir = trim(rates_dir) // '/rate_tables'
544 3 : filename = trim(dir) // '/rate_list.txt'
545 3 : ierr = 0
546 3 : open(newunit=iounit, file=trim(filename), action='read', status='old', iostat=ierr)
547 3 : if (ierr /= 0) then
548 0 : write(*,*) 'failed to open rates list file ' // trim(filename)
549 0 : return
550 : end if
551 : end if
552 21 : rates_table_dir = dir
553 :
554 21 : n = 0
555 21 : i = 0
556 :
557 : if (dbg) write(*,*) 'read rate list file ' // trim(filename)
558 :
559 69 : rate_loop: do
560 90 : t = token(iounit, n, i, buffer, rate_name)
561 90 : if (t == eof_token) exit rate_loop
562 69 : if (t /= name_token) then
563 0 : call error; return
564 : end if
565 : if (dbg) write(*,*) 'use rate table from file for ', trim(rate_name)
566 69 : t = token(iounit, n, i, buffer, rate_fname)
567 69 : if (t /= string_token) then
568 0 : call error; return
569 : end if
570 :
571 69 : call rate_from_file(rate_name, rate_fname, ierr)
572 90 : if (ierr /= 0) call error()
573 :
574 : end do rate_loop
575 :
576 21 : close(iounit)
577 :
578 : if (dbg) call mesa_error(__FILE__,__LINE__,'read rates')
579 : !call check
580 :
581 :
582 : contains
583 :
584 :
585 : subroutine check
586 : ! check that there are cases for all of the rates
587 : use ratelib, only: tfactors
588 : use raw_rates, only: set_raw_rate
589 : real(dp) :: logT, temp, raw_rate
590 : integer :: i, ierr
591 : type (T_Factors) :: tf
592 :
593 : logT = 8
594 : temp = exp10(logT)
595 : call tfactors(tf, logT, temp)
596 : ierr = 0
597 : okay = .true.
598 : do i = 1, rates_reaction_id_max
599 : call set_raw_rate(i, temp, tf, raw_rate, ierr)
600 : if (ierr /= 0) then
601 : write(*,'(a)') 'set_raw_rate failed for ' // reaction_Name(i)
602 : okay = .false.
603 : ierr = 0
604 : end if
605 : end do
606 : if (.not. okay) call mesa_error(__FILE__,__LINE__,'init_raw_rates_records')
607 : end subroutine check
608 :
609 :
610 : logical function failed(str)
611 : character (len=*), intent(in) :: str
612 : failed = .false.
613 : if (ierr == 0) return
614 : if (len_trim(str) > 0) then
615 : write(*,*) trim(str) // ' failed in reading ' // trim(filename)
616 : else ! non-fatal error, so just quietly stop reading
617 : ierr = 0
618 : end if
619 : failed = .true.
620 : return
621 : end function failed
622 :
623 :
624 0 : subroutine error
625 0 : ierr = -1
626 0 : close(iounit)
627 0 : end subroutine error
628 :
629 :
630 : end subroutine init_raw_rates_records
631 :
632 569 : subroutine rate_from_file(rate_name, filename, ierr)
633 : character(len=*) :: rate_name, filename
634 : integer, intent(out) :: ierr
635 :
636 : integer :: ir
637 : logical,parameter :: dbg=.false.
638 : type (rate_table_info), pointer :: ri =>null()
639 :
640 569 : ierr = 0
641 :
642 69 : if (len_trim(rate_name) == 0 .or. len_trim(filename)==0) return
643 :
644 69 : ir = lookup_rate_name(rate_name)
645 69 : if (ir <= 0) then
646 0 : call do_add_reaction_for_handle(rate_name, ierr)
647 0 : if (ierr == 0) ir = lookup_rate_name(rate_name)
648 0 : if (ierr /= 0 .or. ir <= 0) then
649 0 : write(*,*) 'invalid rate file ' // trim(rate_name)
650 0 : ierr = -1
651 0 : return
652 : end if
653 : end if
654 : if (dbg) write(*,*) 'rate_fname ', trim(filename)
655 69 : ri => raw_rates_records(ir)
656 69 : ri% use_rate_table = .true.
657 69 : ri% need_to_read = .true.
658 69 : ri% rate_fname = trim(filename)
659 : if (dbg) write(*,*) 'done'
660 :
661 :
662 569 : end subroutine rate_from_file
663 :
664 :
665 5 : subroutine read_reaction_parameters(reactionlist_filename, ierr)
666 : use utils_lib
667 : use chem_lib
668 : use chem_def, only: chem_isos, category_id, category_Name
669 : character (len=*), intent(in) :: reactionlist_filename
670 : integer, intent(out) :: ierr
671 :
672 : character (len=256) :: line, filename, rname, cname
673 : integer :: iounit, len, i, j, jj, k, cnt, ir, ic, ii, n, num_reactions
674 : character (len=maxlen_reaction_Info) :: info
675 : logical, parameter :: dbg = .false.
676 :
677 : include 'formats'
678 :
679 5 : ierr = 0
680 :
681 5 : call alloc_and_init_reaction_parameters(ierr)
682 5 : if (ierr /= 0) return
683 :
684 : ! first try the reaction_filename alone
685 5 : filename = trim(reactionlist_filename)
686 5 : open(newunit=iounit, file=trim(filename), action='read', status='old', iostat=ierr)
687 5 : if (ierr /= 0) then ! if don't find that file, look in rates_data
688 5 : filename = trim(mesa_data_dir) // '/rates_data/' // trim(reactionlist_filename)
689 5 : ierr = 0
690 5 : open(newunit=iounit, file=trim(filename), action='read', status='old', iostat=ierr)
691 5 : if (ierr /= 0) then
692 : write(*,*) &
693 0 : 'failed to open reaction_parameters file ' // trim(reactionlist_filename)
694 0 : return
695 : end if
696 : end if
697 :
698 5 : num_reactions = 0
699 1965 : do cnt = 1, rates_reaction_id_max*10 ! will stop when reach end of file
700 : if (dbg) write(*, *) 'cnt', cnt
701 :
702 1965 : read(iounit,'(a)',iostat=ierr) line
703 1965 : if (ierr /= 0) then
704 : if (dbg) write(*,*) 'reached end of file'
705 : exit
706 : end if
707 1960 : len = len_trim(line)
708 1960 : if (len == 0) then
709 : if (dbg) write(*,*) '(len == 0)'
710 : cycle
711 : end if
712 1770 : if (line(1:1) == '!') then
713 : if (dbg) write(*,*) '(line(1:1) == !)'
714 : cycle
715 : end if
716 :
717 1590 : i = 1; j = 35
718 1590 : rname = line(i:j)
719 :
720 : if (dbg) write(*,*) trim(rname)
721 :
722 1590 : if (line(i:i+1) == 'r ') then
723 0 : call increase_num_reactions(ierr)
724 0 : if (ierr /= 0) then
725 0 : write(*,*) 'FATAL ERROR: rates_def_init failed in increase_num_reactions'
726 0 : return
727 : end if
728 0 : ir = rates_reaction_id_max
729 : else
730 1590 : ir = get_rates_reaction_id(rname)
731 : end if
732 : if (dbg) write(*,*) 'name: ' // trim(rname), ir
733 1590 : if (ir == 0) then
734 50 : call increase_num_reactions(ierr)
735 50 : if (ierr /= 0) then
736 0 : write(*,*) 'FATAL ERROR: rates_def_init failed in increase_num_reactions'
737 0 : return
738 : end if
739 50 : ir = rates_reaction_id_max
740 : if (dbg) write(*,*) 'size(reaction_Name,dim=1), ir', size(reaction_Name,dim=1), ir
741 50 : reaction_Name(ir) = rname
742 50 : call integer_dict_define(reaction_names_dict, reaction_Name(ir), ir, ierr)
743 50 : if (ierr /= 0) then
744 0 : write(*,*) 'FATAL ERROR: rates_def_init failed in integer_dict_define'
745 0 : call mesa_error(__FILE__,__LINE__)
746 : end if
747 : end if
748 :
749 1590 : i = 36; j = 70
750 1590 : call read_inputs
751 1590 : if (ierr /= 0) return
752 :
753 1590 : i = 74; j = 108
754 1590 : call read_outputs
755 1590 : if (ierr /= 0) return
756 :
757 1590 : i = 110; j = 127
758 1590 : call read_Q
759 1590 : if (ierr /= 0) return
760 :
761 1590 : i = 128; j = 143
762 1590 : call read_Qneu
763 1590 : if (ierr /= 0) return
764 :
765 1590 : i = 144; j = 149
766 1590 : call read_ye_rho_exponent1
767 1590 : if (ierr /= 0) return
768 :
769 1590 : i = 150; j = 155
770 1590 : call read_ye_rho_exponent2
771 1590 : if (ierr /= 0) return
772 :
773 1590 : i = 156; j = 160
774 1590 : call read_screening_info(1)
775 1590 : if (ierr /= 0) return
776 :
777 1590 : i = 162; j = 166
778 1590 : call read_screening_info(2)
779 1590 : if (ierr /= 0) return
780 :
781 1590 : i = 168; j = 172
782 1590 : call read_screening_info(3)
783 1590 : if (ierr /= 0) return
784 :
785 1590 : i = 174; j = 178
786 1590 : call read_weak_info(1)
787 1590 : if (ierr /= 0) return
788 :
789 1590 : i = 180; j = 184
790 1590 : call read_weak_info(2)
791 1590 : if (ierr /= 0) return
792 :
793 1590 : if (std_reaction_neuQs(ir) > 0) then
794 200 : weak_reaction_info(1,ir) = reaction_inputs(2,ir)
795 200 : weak_reaction_info(2,ir) = reaction_outputs(2,ir)
796 : end if
797 :
798 : if (std_reaction_neuQs(ir) == 0 .and. &
799 1590 : weak_reaction_info(1,ir) > 0 .and. weak_reaction_info(2,ir) > 0) then
800 : j = do_get_weak_info_list_id( &
801 : chem_isos% name(weak_reaction_info(1,ir)), &
802 0 : chem_isos% name(weak_reaction_info(2,ir)))
803 0 : if (j > 0) std_reaction_neuQs(ir) = weak_info_list_Qneu(j)
804 0 : if (ierr /= 0) return
805 : end if
806 :
807 1590 : if (std_reaction_neuQs(ir) > 0) then
808 200 : call set_weak_lowT_rate(ir, ierr)
809 200 : if (ierr /= 0) return
810 : end if
811 :
812 1590 : i = 190; j = 203
813 1590 : call read_category_id
814 1590 : if (ierr /= 0) return
815 :
816 1590 : i = 208
817 1590 : call read_reaction_Info
818 1590 : if (ierr /= 0) return
819 :
820 : if (dbg) write(*,*)
821 :
822 1590 : num_reactions = cnt
823 :
824 : end do
825 :
826 : if (dbg) write(*,*) 'num_reactions', num_reactions
827 :
828 5 : ierr = 0
829 5 : close(iounit)
830 :
831 5 : num_reactions = rates_reaction_id_max
832 :
833 5 : call check_std_reaction_Qs
834 5 : call check_std_reaction_neuQs
835 5 : call check_reaction_categories
836 5 : call check_reaction_info
837 :
838 10 : if (dbg) call mesa_error(__FILE__,__LINE__,'read_reaction_parameters')
839 :
840 :
841 : contains
842 :
843 :
844 1590 : subroutine read_inputs
845 : if (dbg) write(*,*) ' inputs <' // line(i:j) // '>',i,j
846 :
847 1590 : jj = j
848 1590 : do k = 1, 2*max_num_reaction_inputs-1, 2
849 3565 : j = i; j = i+2
850 3565 : n = read_int()
851 3565 : if (n == 0) exit
852 : if (dbg) write(*,*) 'n <' // line(i:j) // '>', i, j
853 2035 : reaction_inputs(k,ir) = n
854 :
855 : ! fxt
856 2035 : i = j+1; j = i+7
857 :
858 : ! i = j+1; j = i+4
859 :
860 : if (dbg) write(*,*) 'iso <' // line(i:j) // '>', i, j
861 2035 : ii = read_iso()
862 2035 : if (ii <= 0) then
863 0 : write(*,'(a)') 'bad input iso in reaction_parameters file <' // line(i:j) // '>'
864 0 : write(*,'(a)') trim(line)
865 0 : call mesa_error(__FILE__,__LINE__,'read_reaction_parameters')
866 0 : ierr = -1
867 0 : return
868 : end if
869 2035 : i = j+2
870 2035 : reaction_inputs(k+1,ir) = ii
871 1590 : if (dbg) write(*,*) 'in', n, trim(chem_isos% name(ii)), i
872 : end do
873 5 : end subroutine read_inputs
874 :
875 :
876 1590 : subroutine read_outputs
877 : if (dbg) write(*,*) ' outputs: ' // line(i:j)
878 :
879 1590 : jj = j
880 1590 : do k = 1, 2*max_num_reaction_outputs-1, 2
881 3415 : j = i; j = i+2
882 3415 : n = read_int()
883 3415 : if (n == 0) exit
884 : if (dbg) write(*,*) 'n <' // line(i:j) // '>'
885 1825 : reaction_outputs(k,ir) = n
886 :
887 : ! fxt
888 1825 : i = j+1; j = i+7
889 :
890 : ! i = j+1; j = i+4
891 :
892 : if (dbg) write(*,*) 'iso <' // line(i:j) // '>'
893 1825 : ii = read_iso()
894 1825 : if (ii <= 0) then
895 0 : write(*,'(a)') 'bad output iso in reaction_parameters file <' // line(i:j) // '>'
896 0 : write(*,'(a)') trim(line)
897 0 : call mesa_error(__FILE__,__LINE__,'read_reaction_parameters')
898 0 : ierr = -1
899 0 : return
900 : end if
901 1825 : i = j+2
902 1825 : reaction_outputs(k+1,ir) = ii
903 1590 : if (dbg) write(*,*) 'out', n, trim(chem_isos% name(ii))
904 : end do
905 : end subroutine read_outputs
906 :
907 :
908 1590 : subroutine read_Q
909 1590 : if (missing_dbl()) then ! use standard Q from chem_lib
910 1540 : std_reaction_Qs(ir) = get_Qtotal(ir)
911 : else
912 50 : std_reaction_Qs(ir) = read_dbl()
913 : if (dbg) write(*,*) 'std_reaction_Qs(ir)', std_reaction_Qs(ir)
914 : end if
915 1590 : end subroutine read_Q
916 :
917 :
918 1590 : subroutine read_Qneu
919 : include 'formats'
920 1590 : std_reaction_neuQs(ir) = read_dbl()
921 : if (dbg) write(*,1) 'std_reaction_neuQs(ir)', std_reaction_neuQs(ir)
922 1590 : end subroutine read_Qneu
923 :
924 :
925 1590 : subroutine read_ye_rho_exponent1
926 1590 : reaction_ye_rho_exponents(1,ir) = read_int()
927 : if (dbg) write(*,*) 'ye', reaction_ye_rho_exponents(1,ir)
928 1590 : if (reaction_ye_rho_exponents(1,ir) > 2) then
929 0 : write(*,'(a)') 'ERROR: must revise rates_support for large ye exponent'
930 0 : write(*,'(a)') trim(line)
931 0 : call mesa_error(__FILE__,__LINE__,'read_reaction_parameters')
932 : end if
933 1590 : end subroutine read_ye_rho_exponent1
934 :
935 :
936 1590 : subroutine read_ye_rho_exponent2
937 1590 : ii = read_int()
938 1590 : if (ii > 0) ii = ii-1
939 1590 : reaction_ye_rho_exponents(2,ir) = ii
940 1590 : if (ii > 4) then
941 0 : write(*,'(a)') 'ERROR: must revise rates_support for large rho exponent'
942 0 : write(*,'(a)') trim(line)
943 0 : call mesa_error(__FILE__,__LINE__,'read_reaction_parameters')
944 : end if
945 : if (dbg) write(*,*) 'rho', reaction_ye_rho_exponents(2,ir)+1
946 1590 : end subroutine read_ye_rho_exponent2
947 :
948 :
949 4770 : subroutine read_screening_info(which)
950 : integer, intent(in) :: which
951 : logical :: empty
952 : integer :: jj
953 4770 : ii = read_iso()
954 4770 : reaction_screening_info(which,ir) = ii
955 :
956 : !Hack to get around a bug in ifort 17,18, which returns len_trim(line(i:j)) < 0
957 4770 : empty=.true.
958 28620 : do jj=i,j
959 28620 : if(len_trim(line(jj:jj)) /= 0) empty=.false.
960 : end do
961 :
962 4770 : if (ii <= 0 .and. .not. empty) then
963 0 : write(*,'(a)') 'bad iso name for screening in reaction_parameters file <' // line(i:j) // '>'
964 0 : write(*,'(a)') trim(line)
965 0 : call mesa_error(__FILE__,__LINE__,'read_screening_info')
966 0 : ierr = -1
967 0 : return
968 : end if
969 : if (dbg .and. ii > 0) &
970 : write(*,*) 'screen: ' // trim(chem_isos% name(ii)) // ' ' // line(i:j), ii
971 : end subroutine read_screening_info
972 :
973 :
974 3180 : subroutine read_weak_info(which)
975 : integer, intent(in) :: which
976 : logical :: empty
977 : integer :: jj
978 :
979 3180 : ii = read_iso()
980 3180 : weak_reaction_info(which,ir) = ii
981 :
982 : !Hack to get around a bug in ifort 7, 18 which returns len_trim(line(i:j)) < 0
983 3180 : empty=.true.
984 19080 : do jj=i,j
985 19080 : if(len_trim(line(jj:jj)) /= 0) empty=.false.
986 : end do
987 :
988 3180 : if (ii <= 0 .and. .not. empty) then
989 0 : write(*,'(a)') 'bad iso name for weak in reaction_parameters file <' // line(i:j) // '>'
990 0 : write(*,'(a)') trim(line)
991 0 : call mesa_error(__FILE__,__LINE__,'read_reaction_parameters len')
992 0 : ierr = -1
993 0 : return
994 : end if
995 3180 : if (ii > 0) then
996 0 : write(*,*) 'weak: ' // trim(chem_isos% name(ii)) // ' ' // line(i:j), ii
997 0 : write(*,'(a)') trim(line)
998 0 : write(*,'(a)') 'DO NOT USE reactions.list FOR WEAK ISOS; just give Qneu'
999 0 : call mesa_error(__FILE__,__LINE__,'read_reaction_parameters weak')
1000 0 : ierr = -1
1001 0 : return
1002 : end if
1003 : end subroutine read_weak_info
1004 :
1005 :
1006 1590 : subroutine read_category_id
1007 1590 : cname = line(i:j)
1008 1590 : ic = category_id(cname)
1009 1590 : if (ic == 0) then
1010 0 : write(*,*) 'bad category name in reaction_parameters file <' // line(i:j) // '>'
1011 0 : write(*,'(a)') trim(line)
1012 0 : call mesa_error(__FILE__,__LINE__,'read_category_id')
1013 0 : ierr = -1
1014 0 : return
1015 : end if
1016 1590 : reaction_categories(ir) = ic
1017 : if (dbg) write(*,*) 'category: ' // trim(cname), ic, trim(category_name(ic))
1018 : end subroutine read_category_id
1019 :
1020 :
1021 1590 : subroutine read_reaction_Info
1022 1590 : ii = min(maxlen_reaction_Info, len - i + 1)
1023 116070 : do j = 1, maxlen_reaction_Info
1024 116070 : if (j <= ii) then
1025 45655 : info(j:j) = line(i:i)
1026 45655 : i = i+1
1027 : else
1028 68825 : info(j:j) = ' '
1029 : end if
1030 : end do
1031 1590 : reaction_Info(ir) = info
1032 : if (dbg) write(*,*) 'info: ' // trim(reaction_Info(ir))
1033 1590 : end subroutine read_reaction_Info
1034 :
1035 :
1036 11810 : integer function read_iso()
1037 : use chem_def, only: iso_name_length
1038 : character (len=64) :: str
1039 11810 : str = line(i:j)
1040 11810 : read_iso = chem_get_iso_id(str)
1041 11810 : end function read_iso
1042 :
1043 :
1044 10160 : integer function read_int()
1045 : character (len=64) :: str
1046 : integer :: ierr
1047 10160 : str = line(i:j)
1048 10160 : read(str,fmt=*,iostat=ierr) read_int
1049 10160 : if (ierr /= 0) read_int = 0
1050 11810 : end function read_int
1051 :
1052 :
1053 1640 : real(dp) function read_dbl()
1054 : use math_lib, only: str_to_double
1055 : integer :: ierr
1056 1640 : ierr = 0
1057 1640 : if (len_trim(line(i:j)) > 0) then
1058 295 : call str_to_double(line(i:j),read_dbl,ierr)
1059 295 : if (ierr /= 0) read_dbl = 0d0
1060 : else
1061 1345 : read_dbl = 0d0
1062 : end if
1063 1640 : end function read_dbl
1064 :
1065 :
1066 1590 : logical function missing_dbl()
1067 : character (len=64) :: str
1068 1590 : str = line(i:j)
1069 1590 : missing_dbl = (len_trim(str) == 0)
1070 1640 : end function missing_dbl
1071 :
1072 :
1073 5 : subroutine check_std_reaction_Qs
1074 : integer :: i, cnt
1075 5 : cnt = 0
1076 1590 : do i=1,num_reactions
1077 1590 : if (std_reaction_Qs(i) < -1d50) then
1078 0 : write(*,*) 'missing reaction_Q for reaction ' // trim(reaction_Name(i)), i, cnt+1
1079 0 : write(*,*)
1080 0 : cnt = cnt+1
1081 : end if
1082 : end do
1083 5 : if (cnt > 0) call mesa_error(__FILE__,__LINE__,'check_std_reaction_Qs')
1084 5 : end subroutine check_std_reaction_Qs
1085 :
1086 :
1087 5 : subroutine check_std_reaction_neuQs
1088 : integer :: i, cnt
1089 5 : cnt = 0
1090 1590 : do i=1,num_reactions
1091 1590 : if (std_reaction_neuQs(i) < -1d50) then
1092 0 : write(*,*) 'missing std_reaction_neuQs for reaction ' // trim(reaction_Name(i))
1093 0 : write(*,*)
1094 0 : cnt = cnt+1
1095 : end if
1096 : end do
1097 5 : if (cnt > 0) call mesa_error(__FILE__,__LINE__,'check_std_reaction_neuQs')
1098 5 : end subroutine check_std_reaction_neuQs
1099 :
1100 :
1101 5 : subroutine check_reaction_categories
1102 : integer :: cnt, i
1103 5 : cnt = 0
1104 1590 : do i=1,num_reactions
1105 1590 : if (reaction_categories(i) < 0) then
1106 0 : write(*,*) 'missing reaction_category for reaction ' // trim(reaction_Name(i))
1107 0 : write(*,*)
1108 0 : cnt = cnt+1
1109 : end if
1110 : end do
1111 5 : if (cnt > 0) call mesa_error(__FILE__,__LINE__,'check_reaction_categories')
1112 5 : end subroutine check_reaction_categories
1113 :
1114 :
1115 5 : subroutine check_reaction_info
1116 : integer :: i, cnt
1117 5 : cnt = 0
1118 1590 : do i=1,num_reactions
1119 1590 : if (len_trim(reaction_Info(i)) == 0) then
1120 0 : write(*,*) 'missing info for reaction', i
1121 0 : if (i > 1) write(*,*) 'following ' // trim(reaction_Info(i-1))
1122 0 : write(*,*)
1123 0 : cnt = cnt+1
1124 : end if
1125 : end do
1126 5 : if (cnt > 0) call mesa_error(__FILE__,__LINE__,'check_reaction_info')
1127 5 : end subroutine check_reaction_info
1128 :
1129 :
1130 : end subroutine read_reaction_parameters
1131 :
1132 :
1133 68 : subroutine increase_num_reactions(ierr)
1134 : integer, intent(out) :: ierr
1135 :
1136 : integer :: old_max, new_max, i
1137 : type (rate_table_info), pointer :: old_raw_rates_records(:) =>null()
1138 : type (rate_table_info), pointer :: ri =>null()
1139 :
1140 : include 'formats'
1141 :
1142 68 : old_max = rates_reaction_id_max
1143 68 : rates_reaction_id_max = rates_reaction_id_max + 1
1144 :
1145 68 : if (rates_reaction_id_max > size(std_reaction_Qs,dim=1)) then
1146 :
1147 5 : new_max = rates_reaction_id_max*2 + 1000
1148 : !write(*,3) 'increase size', rates_reaction_id_max, new_max
1149 :
1150 5 : old_raw_rates_records => raw_rates_records
1151 5 : allocate(raw_rates_records(new_max))
1152 1540 : do i=1,old_max
1153 1540 : raw_rates_records(i) = old_raw_rates_records(i)
1154 : end do
1155 5 : deallocate(old_raw_rates_records)
1156 :
1157 5 : call grow_reactions_arrays(old_max, new_max, ierr)
1158 5 : if (ierr /= 0) return
1159 : end if
1160 :
1161 68 : ri => raw_rates_records(rates_reaction_id_max)
1162 68 : ri% nT8s = 0
1163 68 : ri% use_rate_table = .false.
1164 68 : ri% need_to_read = .false.
1165 68 : nullify(ri% T8s)
1166 68 : nullify(ri% f1)
1167 :
1168 : end subroutine increase_num_reactions
1169 :
1170 :
1171 5 : subroutine alloc_and_init_reaction_parameters(ierr)
1172 : integer, intent(out) :: ierr
1173 :
1174 : allocate( &
1175 : reaction_Info(rates_reaction_id_max), &
1176 : reaction_categories(rates_reaction_id_max), &
1177 : reaction_is_reverse(rates_reaction_id_max), &
1178 : reaction_reaclib_lo(rates_reaction_id_max), &
1179 : reaction_reaclib_hi(rates_reaction_id_max), &
1180 : reverse_reaction_id(rates_reaction_id_max), &
1181 : reaction_screening_info(3,rates_reaction_id_max), &
1182 : weak_reaction_info(2,rates_reaction_id_max), &
1183 : reaction_ye_rho_exponents(2,rates_reaction_id_max), &
1184 : reaction_inputs(2*max_num_reaction_inputs,rates_reaction_id_max), &
1185 : reaction_outputs(2*max_num_reaction_outputs,rates_reaction_id_max), &
1186 : std_reaction_Qs(rates_reaction_id_max), &
1187 : std_reaction_neuQs(rates_reaction_id_max), &
1188 : weak_lowT_rate(rates_reaction_id_max), &
1189 5 : stat=ierr)
1190 5 : if (ierr /= 0) return
1191 :
1192 1540 : reaction_Info(:) = ''
1193 1540 : reaction_categories(:) = -1
1194 1540 : reaction_is_reverse(:) = 0
1195 1540 : reaction_reaclib_lo(:) = 0
1196 1540 : reaction_reaclib_hi(:) = 0
1197 1540 : reverse_reaction_id(:) = 0
1198 6145 : reaction_screening_info(:,:) = 0
1199 4610 : weak_reaction_info(:,:) = 0
1200 4610 : reaction_ye_rho_exponents(:,:) = 0
1201 10750 : reaction_inputs(:,:) = 0
1202 13820 : reaction_outputs(:,:) = 0
1203 1540 : std_reaction_Qs(:) = -1d99
1204 1540 : std_reaction_neuQs(:) = -1d99
1205 1540 : weak_lowT_rate(:) = -1d99
1206 :
1207 : end subroutine alloc_and_init_reaction_parameters
1208 :
1209 :
1210 1558 : real(dp) function get_Qtotal(ir)
1211 : use chem_lib, only: reaction_Qtotal
1212 : use chem_def, only: chem_isos
1213 : integer, intent(in) :: ir
1214 :
1215 : integer :: num_in, num_out, reactants(100), k, n, i, ii, j
1216 : include 'formats'
1217 1558 : i = 0
1218 2010 : do k = 1, 2*max_num_reaction_inputs-1, 2
1219 3508 : n = reaction_inputs(k,ir)
1220 3508 : if (n == 0) exit
1221 2010 : ii = reaction_inputs(k+1,ir)
1222 5988 : do j = 1, n
1223 2420 : i = i+1
1224 4430 : reactants(i) = ii
1225 : end do
1226 : end do
1227 1558 : num_in = i
1228 3353 : do k = 1, 2*max_num_reaction_outputs-1, 2
1229 3353 : n = reaction_outputs(k,ir)
1230 3353 : if (n == 0) exit
1231 1795 : ii = reaction_outputs(k+1,ir)
1232 5258 : do j = 1, n
1233 1905 : i = i+1
1234 3700 : reactants(i) = ii
1235 : end do
1236 : end do
1237 1558 : num_out = i - num_in
1238 1558 : get_Qtotal = reaction_Qtotal(num_in,num_out,reactants,chem_isos)
1239 1558 : end function get_Qtotal
1240 :
1241 :
1242 20 : subroutine init_rates_info(reactionlist_filename, ierr)
1243 : character (len=*), intent(in) :: reactionlist_filename
1244 : integer, intent(out) :: ierr ! 0 means AOK.
1245 : include 'formats'
1246 :
1247 5 : ierr = 0
1248 5 : call init1_rates_info
1249 :
1250 5 : call start_rates_def_init(ierr)
1251 5 : if (ierr /= 0) then
1252 0 : write(*,*) 'start_rates_def_init failed'
1253 0 : return
1254 : end if
1255 :
1256 5 : call read_reaction_parameters(reactionlist_filename, ierr)
1257 5 : if (ierr /= 0) then
1258 0 : write(*,*) 'rates_init failed in read_reaction_parameters'
1259 0 : return
1260 : end if
1261 :
1262 5 : call finish_rates_def_init
1263 5 : call do_rates_init(ierr)
1264 5 : if (ierr /= 0) then
1265 0 : write(*,*) 'rates_init failed in do_rates_init'
1266 0 : return
1267 : end if
1268 :
1269 1558 : end subroutine init_rates_info
1270 :
1271 :
1272 5 : subroutine init1_rates_info
1273 : use rates_names, only: set_reaction_names
1274 : type (rate_table_info), pointer :: ri =>null()
1275 : integer :: i
1276 5 : rates_reaction_id_max = num_predefined_reactions
1277 : allocate( &
1278 : raw_rates_records(rates_reaction_id_max), &
1279 5 : reaction_Name(rates_reaction_id_max))
1280 1540 : do i = 1, rates_reaction_id_max
1281 1535 : ri => raw_rates_records(i)
1282 1535 : ri% nT8s = 0
1283 1535 : ri% use_rate_table = .false.
1284 1535 : ri% need_to_read = .false.
1285 1535 : nullify(ri% T8s)
1286 1540 : nullify(ri% f1)
1287 : end do
1288 5 : call set_reaction_names
1289 5 : end subroutine init1_rates_info
1290 :
1291 :
1292 69 : integer function lookup_rate_name(str) ! -1 if not found
1293 : use rates_def
1294 : character (len=*), intent(in) :: str
1295 : integer :: i
1296 69 : lookup_rate_name = -1
1297 21297 : do i = 1, rates_reaction_id_max
1298 21297 : if (trim(str) == trim(reaction_Name(i))) then
1299 69 : lookup_rate_name = i
1300 69 : return
1301 : end if
1302 : end do
1303 69 : end function lookup_rate_name
1304 :
1305 5 : subroutine grow_reactions_arrays(old_max, new_max, ierr)
1306 69 : use utils_lib
1307 : integer, intent(in) :: old_max, new_max
1308 : integer, intent(out) :: ierr
1309 :
1310 : character (len=maxlen_reaction_Name), pointer :: new_reaction_Name(:) =>null()
1311 : character (len=maxlen_reaction_Info), pointer :: new_reaction_Info(:) =>null()
1312 : integer :: i
1313 :
1314 : include 'formats'
1315 :
1316 5 : allocate(new_reaction_Name(new_max))
1317 1540 : do i=1,old_max
1318 1540 : new_reaction_Name(i) = reaction_Name(i)
1319 : end do
1320 5 : deallocate(reaction_Name)
1321 5 : reaction_Name => new_reaction_Name
1322 :
1323 5 : allocate(new_reaction_Info(new_max))
1324 1540 : do i=1,old_max
1325 1540 : new_reaction_Info(i) = reaction_Info(i)
1326 : end do
1327 5 : deallocate(reaction_Info)
1328 5 : reaction_Info => new_reaction_Info
1329 :
1330 5 : call realloc_integer(reaction_categories,new_max,ierr); if (ierr /= 0) return
1331 5 : call realloc_integer(reaction_is_reverse,new_max,ierr); if (ierr /= 0) return
1332 5 : call realloc_integer(reaction_reaclib_lo,new_max,ierr); if (ierr /= 0) return
1333 5 : call realloc_integer(reaction_reaclib_hi,new_max,ierr); if (ierr /= 0) return
1334 5 : call realloc_integer(reverse_reaction_id,new_max,ierr); if (ierr /= 0) return
1335 :
1336 5 : call realloc_double(std_reaction_Qs,new_max,ierr); if (ierr /= 0) return
1337 5 : call realloc_double(std_reaction_neuQs,new_max,ierr); if (ierr /= 0) return
1338 :
1339 5 : call realloc_double(weak_lowT_rate,new_max,ierr); if (ierr /= 0) return
1340 :
1341 : call realloc_integer2( &
1342 : reaction_screening_info,size( &
1343 5 : reaction_screening_info,dim=1),new_max,ierr); if (ierr /= 0) return
1344 : call realloc_integer2( &
1345 5 : weak_reaction_info,2,new_max,ierr); if (ierr /= 0) return
1346 : call realloc_integer2( &
1347 5 : reaction_ye_rho_exponents,2,new_max,ierr); if (ierr /= 0) return
1348 : call realloc_integer2( &
1349 5 : reaction_inputs,2*max_num_reaction_inputs,new_max,ierr); if (ierr /= 0) return
1350 : call realloc_integer2( &
1351 5 : reaction_outputs,2*max_num_reaction_outputs,new_max,ierr); if (ierr /= 0) return
1352 :
1353 6550 : reaction_Info(rates_reaction_id_max:new_max) = ''
1354 6550 : reaction_categories(rates_reaction_id_max:new_max) = -1
1355 :
1356 6550 : reaction_is_reverse(rates_reaction_id_max:new_max) = 0
1357 6550 : reaction_reaclib_lo(rates_reaction_id_max:new_max) = 0
1358 6550 : reaction_reaclib_hi(rates_reaction_id_max:new_max) = 0
1359 6550 : reverse_reaction_id(rates_reaction_id_max:new_max) = 0
1360 :
1361 26185 : reaction_screening_info(:,rates_reaction_id_max:new_max) = 0
1362 19640 : weak_reaction_info(:,rates_reaction_id_max:new_max) = 0
1363 19640 : reaction_ye_rho_exponents(:,rates_reaction_id_max:new_max) = 0
1364 45820 : reaction_inputs(:,rates_reaction_id_max:new_max) = 0
1365 58910 : reaction_outputs(:,rates_reaction_id_max:new_max) = 0
1366 6550 : std_reaction_Qs(rates_reaction_id_max:new_max) = -1d99
1367 6550 : std_reaction_neuQs(rates_reaction_id_max:new_max) = -1d99
1368 6550 : weak_lowT_rate(rates_reaction_id_max:new_max) = -1d99
1369 :
1370 40 : end subroutine grow_reactions_arrays
1371 :
1372 :
1373 3 : subroutine free_reaction_arrays()
1374 :
1375 3 : if (ASSOCIATED(reaction_Name)) deallocate(reaction_Name)
1376 3 : if (ASSOCIATED(reaction_Info)) deallocate(reaction_Info)
1377 :
1378 3 : if (ASSOCIATED(reaction_categories)) deallocate(reaction_categories)
1379 3 : if (ASSOCIATED(reaction_is_reverse)) deallocate(reaction_is_reverse)
1380 3 : if (ASSOCIATED(reaction_reaclib_lo)) deallocate(reaction_reaclib_lo)
1381 3 : if (ASSOCIATED(reaction_reaclib_hi)) deallocate(reaction_reaclib_hi)
1382 3 : if (ASSOCIATED(reverse_reaction_id)) deallocate(reverse_reaction_id)
1383 :
1384 3 : if (ASSOCIATED(std_reaction_Qs)) deallocate(std_reaction_Qs)
1385 3 : if (ASSOCIATED(std_reaction_neuQs)) deallocate(std_reaction_neuQs)
1386 :
1387 3 : if (ASSOCIATED(weak_lowT_rate)) deallocate(weak_lowT_rate)
1388 :
1389 3 : if (ASSOCIATED(reaction_screening_info)) deallocate(reaction_screening_info)
1390 3 : if (ASSOCIATED(weak_reaction_info)) deallocate(weak_reaction_info)
1391 3 : if (ASSOCIATED(reaction_ye_rho_exponents)) deallocate(reaction_ye_rho_exponents)
1392 3 : if (ASSOCIATED(reaction_inputs)) deallocate(reaction_inputs)
1393 3 : if (ASSOCIATED(reaction_outputs)) deallocate(reaction_outputs)
1394 :
1395 3 : nullify(reaction_Name)
1396 3 : nullify(reaction_Info)
1397 3 : nullify(reaction_is_reverse)
1398 3 : nullify(reaction_categories)
1399 3 : nullify(reaction_reaclib_lo)
1400 3 : nullify(reaction_reaclib_hi)
1401 3 : nullify(reverse_reaction_id)
1402 3 : nullify(std_reaction_Qs)
1403 3 : nullify(std_reaction_neuQs)
1404 3 : nullify(weak_lowT_rate)
1405 3 : nullify(reaction_screening_info)
1406 3 : nullify(reaction_ye_rho_exponents)
1407 3 : nullify(reaction_inputs)
1408 3 : nullify(reaction_outputs)
1409 :
1410 3 : end subroutine free_reaction_arrays
1411 :
1412 :
1413 5 : subroutine do_rates_init(ierr)
1414 : use ratelib, only: mazurek_init
1415 : integer, intent(out) :: ierr
1416 : ierr = 0
1417 : ! setup interpolation info for mazurek's 1973 fits for the ni56 electron capture rate
1418 5 : call mazurek_init(ierr)
1419 5 : if (ierr /= 0) return
1420 5 : end subroutine do_rates_init
1421 :
1422 : end module rates_initialize
|