LCOV - code coverage report
Current view: top level - net/public - net_lib.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 41.6 % 315 131
Test Date: 2025-05-08 18:23:42 Functions: 55.6 % 45 25

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010  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 net_lib
      21              :       ! library for calculating nuclear reaction rates and energy production
      22              :       ! the data interface for the library is defined in net_def
      23              : 
      24              :       use chem_def
      25              :       use const_def, only: dp, i8
      26              : 
      27              :       implicit none
      28              : 
      29              :       contains  ! the procedure interface for the library
      30              :       ! client programs should only call these routines.
      31              : 
      32              : 
      33              :       ! call this routine to initialize the net module.
      34              :       ! only needs to be done once at start of run.
      35              : 
      36           19 :       subroutine net_init(ierr)
      37              :          use net_def, only : do_net_def_init
      38              :          use net_initialize, only : init_special_case_reaction_info
      39              :          integer, intent(out) :: ierr  ! 0 means AOK.
      40           19 :          ierr = 0
      41           19 :          call do_net_def_init
      42           19 :          call init_special_case_reaction_info
      43              : 
      44           19 :       end subroutine net_init
      45              : 
      46              : 
      47            3 :       subroutine net_shutdown
      48           19 :       end subroutine net_shutdown
      49              : 
      50              : 
      51              :       ! after net_init has finished, you can allocate a "handle".
      52              : 
      53           19 :       integer function alloc_net_handle(ierr)
      54              :          use net_def, only: do_alloc_net, init_net_handle_data
      55              :          integer, intent(out) :: ierr
      56           19 :          alloc_net_handle = do_alloc_net(ierr)
      57              :          if (ierr /= 0) return
      58              :       end function alloc_net_handle
      59              : 
      60           15 :       subroutine free_net_handle(handle)
      61              :          ! frees the handle and all associated data
      62              :          use net_def, only: do_free_net
      63              :          integer, intent(in) :: handle
      64           15 :          call do_free_net(handle)
      65           15 :       end subroutine free_net_handle
      66              : 
      67              :       ! if you want to access the Net_General_Info record directly,
      68              :       ! you'll need a pointer to it.
      69           19 :       subroutine net_ptr(handle, g, ierr)
      70              :          use net_def, only: Net_General_Info, get_net_ptr
      71              :          integer, intent(in) :: handle  ! from alloc_net_handle
      72              :          type (Net_General_Info), pointer :: g
      73              :          integer, intent(out):: ierr
      74           19 :          call get_net_ptr(handle, g, ierr)
      75           19 :       end subroutine net_ptr
      76              : 
      77              : 
      78              :       ! routines for defining the net isos and reactions
      79              : 
      80              : 
      81              :       ! call this before starting to define
      82              :       ! the set of isotopes and reactions for the net.
      83           19 :       subroutine net_start_def(handle, ierr)
      84              :          use net_initialize, only:start_net_def
      85              :          integer, intent(in) :: handle
      86              :          integer, intent(out) :: ierr
      87           19 :          call start_net_def(handle, ierr)
      88           19 :       end subroutine net_start_def
      89              : 
      90              : 
      91              :       ! call this after you've finished defining
      92              :       ! the set of isotopes and reactions for the net.
      93           19 :       subroutine net_finish_def(handle, ierr)
      94           19 :          use net_initialize, only: finish_net_def
      95              :          integer, intent(in) :: handle
      96              :          integer, intent(out) :: ierr
      97           19 :          call finish_net_def(handle, ierr)
      98           19 :       end subroutine net_finish_def
      99              : 
     100              :       ! note: after net_finish_def returns,
     101              :       ! you have the option of reordering the isotopes
     102              :       ! before you set up the full set of tables for the net.
     103              :       ! use get_chem_id_table_ptr and get_net_iso_table_ptr
     104              :       ! and change both tables to permute the set of isotopes.
     105              :       ! the default isotope ordering is by increasing chem_id number.
     106              : 
     107              : 
     108              :       ! read_net_file first tries opening the filename in the current directory.
     109              :       ! if doesn't find that file, then tries the data_dir from the call on net_init.
     110              :       ! i.e., looks for <data_dir>/net_data/nets/<filename>
     111              :       ! check net_data/nets/README for info about net files.
     112           19 :       subroutine read_net_file(filename, handle, ierr)
     113           19 :          use net_initialize, only: do_read_net_file
     114              :          character (len=*), intent(in) :: filename
     115              :          integer, intent(in) :: handle
     116              :          integer, intent(out) :: ierr
     117           19 :          call do_read_net_file(filename, handle, ierr)
     118           19 :       end subroutine read_net_file
     119              : 
     120              : 
     121            0 :       subroutine net_add_iso(handle, iso_id, ierr)
     122           19 :          use net_initialize, only:add_net_iso
     123              :          integer, intent(in) :: handle
     124              :          integer, intent(in) :: iso_id
     125              :          integer, intent(out) :: ierr
     126            0 :          call add_net_iso(handle, iso_id, ierr)
     127            0 :       end subroutine net_add_iso
     128              : 
     129              : 
     130            0 :       subroutine net_add_isos(handle, num_isos, iso_ids, ierr)
     131            0 :          use net_initialize, only:add_net_isos
     132              :          integer, intent(in) :: handle
     133              :          integer, intent(in) :: num_isos, iso_ids(num_isos)
     134              :          integer, intent(out) :: ierr
     135            0 :          call add_net_isos(handle, num_isos, iso_ids, ierr)
     136            0 :       end subroutine net_add_isos
     137              : 
     138              : 
     139            0 :       subroutine net_remove_iso(handle, iso_id, ierr)
     140            0 :          use net_initialize, only:remove_net_iso
     141              :          integer, intent(in) :: handle
     142              :          integer, intent(in) :: iso_id
     143              :          integer, intent(out) :: ierr
     144            0 :          call remove_net_iso(handle, iso_id, ierr)
     145            0 :       end subroutine net_remove_iso
     146              : 
     147              : 
     148            0 :       subroutine net_remove_isos(handle, num_isos, iso_ids, ierr)
     149            0 :          use net_initialize, only:remove_net_isos
     150              :          integer, intent(in) :: handle
     151              :          integer, intent(in) :: num_isos, iso_ids(num_isos)
     152              :          integer, intent(out) :: ierr
     153            0 :          call remove_net_isos(handle, num_isos, iso_ids, ierr)
     154            0 :       end subroutine net_remove_isos
     155              : 
     156              : 
     157            0 :       subroutine net_add_reaction(handle, reaction_id, ierr)
     158            0 :          use net_initialize, only:add_net_reaction
     159              :          integer, intent(in) :: handle
     160              :          integer, intent(in) :: reaction_id
     161              :          integer, intent(out) :: ierr
     162            0 :          call add_net_reaction(handle, reaction_id, ierr)
     163            0 :       end subroutine net_add_reaction
     164              : 
     165              : 
     166            0 :       subroutine net_add_reactions(handle, num_reactions, reaction_ids, ierr)
     167            0 :          use net_initialize, only:add_net_reactions
     168              :          integer, intent(in) :: handle
     169              :          integer, intent(in) :: num_reactions, reaction_ids(num_reactions)
     170              :          integer, intent(out) :: ierr
     171            0 :          call add_net_reactions(handle, num_reactions, reaction_ids, ierr)
     172            0 :       end subroutine net_add_reactions
     173              : 
     174              : 
     175            0 :       subroutine net_remove_reaction(handle, reaction_id, ierr)
     176            0 :          use net_initialize, only:remove_net_reaction
     177              :          integer, intent(in) :: handle
     178              :          integer, intent(in) :: reaction_id
     179              :          integer, intent(out) :: ierr
     180            0 :          call remove_net_reaction(handle, reaction_id, ierr)
     181            0 :       end subroutine net_remove_reaction
     182              : 
     183              : 
     184            0 :       subroutine net_remove_reactions(handle, num_reactions, reaction_ids, ierr)
     185            0 :          use net_initialize, only:remove_net_reactions
     186              :          integer, intent(in) :: handle
     187              :          integer, intent(in) :: num_reactions, reaction_ids(num_reactions)
     188              :          integer, intent(out) :: ierr
     189            0 :          call remove_net_reactions(handle, num_reactions, reaction_ids, ierr)
     190            0 :       end subroutine net_remove_reactions
     191              : 
     192              : 
     193            0 :       subroutine show_net_reactions(handle, iounit, ierr)
     194            0 :          use net_def
     195              :          use rates_def, only: reaction_Name
     196              :          integer, intent(in) :: handle
     197              :          integer, intent(in) :: iounit
     198              :          integer, intent(out) :: ierr
     199              :          integer :: i, id
     200              :          type (Net_General_Info), pointer  :: g
     201              :          ierr = 0
     202            0 :          call get_net_ptr(handle, g, ierr)
     203            0 :          if (ierr /= 0) return
     204            0 :          do i = 1, g% num_reactions
     205            0 :             id = g% reaction_id(i)
     206            0 :             if (id > 0) write(iounit,'(a)') trim(reaction_Name(id))
     207              :          end do
     208            0 :       end subroutine show_net_reactions
     209              : 
     210              : 
     211            0 :       subroutine show_net_reactions_and_info(handle, iounit, ierr)
     212            0 :          use net_def
     213              :          use rates_def, only:  &
     214              :                reaction_Name, reaction_Info, maxlen_reaction_Info, &
     215              :                std_reaction_Qs, std_reaction_neuQs, reaction_categories
     216              :          integer, intent(in) :: handle
     217              :          integer, intent(in) :: iounit
     218              :          integer, intent(out) :: ierr
     219              :          integer :: i, id, weak_id, icat
     220            0 :          real(dp) :: Q, Qneu
     221              :          logical :: weaklib_reaction
     222              :          character (len=maxlen_reaction_Info) :: info
     223              :          type (Net_General_Info), pointer  :: g
     224              :          ierr = 0
     225            0 :          call get_net_ptr(handle, g, ierr)
     226            0 :          if (ierr /= 0) return
     227            0 :          write(iounit,'(A)')
     228            0 :          write(iounit,'(4x,a30,3a16,4x,a4,4x,a20)') 'name', 'Qtotal', 'Qneu', 'category', 'info', 'source'
     229            0 :          do i = 1, g% num_reactions
     230            0 :             id = g% reaction_id(i)
     231            0 :             weaklib_reaction = .false.
     232            0 :             weak_id = g% weak_reaction_index(i)
     233            0 :             if (weak_id > 0) then
     234            0 :                if (g% weaklib_ids(weak_id) > 0) weaklib_reaction = .true.
     235              :             end if
     236            0 :             if (id > 0) then
     237            0 :                info = reaction_Info(id)
     238            0 :                if (reaction_Name(id) == info) info = ''
     239            0 :                Q = std_reaction_Qs(id)
     240            0 :                Qneu = std_reaction_neuQs(id)
     241            0 :                icat = reaction_categories(id)
     242            0 :                if (weaklib_reaction) then
     243            0 :                   write(iounit,'(i4,a30,16x,a7,9x,4x,a10,4x,a66)') i, &
     244            0 :                         trim(reaction_Name(id)), 'weaklib', trim(category_name(icat)), info
     245            0 :                else if (Qneu /= 0) then
     246            0 :                   write(iounit,'(i4,a30,2f16.6,4x,a10,4x,a66)') i, trim(reaction_Name(id)),  &
     247            0 :                         Q, Qneu, trim(category_name(icat)), info
     248            0 :                else if (Q /= 0) then
     249            0 :                   write(iounit,'(i4,a30,f16.6,16x,4x,a10,4x,a66)') i, trim(reaction_Name(id)),  &
     250            0 :                         Q, trim(category_name(icat)), info
     251              :                else
     252            0 :                   write(iounit,'(i4,a30,16x,16x,4x,a10,4x,a66)') i, trim(reaction_Name(id)),  &
     253            0 :                         trim(category_name(icat)), info
     254              :                end if
     255              :             end if
     256              :          end do
     257            0 :          write(iounit,'(A)')
     258            0 :       end subroutine show_net_reactions_and_info
     259              : 
     260              : 
     261            0 :       subroutine show_net_species(handle, iounit, ierr)
     262            0 :          use net_def
     263              :          use chem_def
     264              :          integer, intent(in) :: handle
     265              :          integer, intent(in) :: iounit
     266              :          integer, intent(out) :: ierr
     267              :          integer :: i, id
     268              :          type (Net_General_Info), pointer  :: g
     269              :          ierr = 0
     270            0 :          call get_net_ptr(handle, g, ierr)
     271            0 :          if (ierr /= 0) return
     272            0 :          do i = 1, g% num_isos
     273            0 :             id = g% chem_id(i)
     274            0 :             if (id > 0) write(iounit,'(i4,a10)') i, trim(chem_isos% name(id))
     275              :          end do
     276            0 :       end subroutine show_net_species
     277              : 
     278              : 
     279            0 :       subroutine show_net_params(handle, iounit, ierr)
     280            0 :          use net_def
     281              :          integer, intent(in) :: handle
     282              :          integer, intent(in) :: iounit
     283              :          integer, intent(out) :: ierr
     284              :          integer :: i, id
     285              :          type (Net_General_Info), pointer  :: g
     286              :          include 'formats'
     287              :          ierr = 0
     288            0 :          call get_net_ptr(handle, g, ierr)
     289            0 :          if (ierr /= 0) return
     290            0 :          write(iounit,2) 'logTcut_lo =', g% logTcut_lo
     291            0 :          write(iounit,2) 'logTcut_lim =', g% logTcut_lim
     292              :       end subroutine show_net_params
     293              : 
     294            1 :       subroutine net_set_fe56ec_fake_factor( &
     295              :             handle, fe56ec_fake_factor, min_T_for_fe56ec_fake_factor, ierr)
     296              :          use net_def, only: do_net_set_fe56ec_fake_factor
     297              :          integer, intent(in) :: handle
     298              :          real(dp), intent(in) :: fe56ec_fake_factor, min_T_for_fe56ec_fake_factor
     299              :          integer, intent(out) :: ierr
     300              :          ierr = 0
     301              :          call do_net_set_fe56ec_fake_factor( &
     302            1 :             handle, fe56ec_fake_factor, min_T_for_fe56ec_fake_factor, ierr)
     303              :          if (ierr /= 0) return
     304              :       end subroutine net_set_fe56ec_fake_factor
     305              : 
     306              : 
     307            1 :       subroutine net_set_logTcut(handle, logTcut_lo, logTcut_lim, ierr)
     308              :          use net_def, only: do_net_set_logTcut
     309              :          integer, intent(in) :: handle
     310              :          real(dp), intent(in) :: logTcut_lo
     311              :          real(dp), intent(in) :: logTcut_lim
     312              :          integer, intent(out) :: ierr
     313              :          ierr = 0
     314            1 :          call do_net_set_logTcut(handle, logTcut_lo, logTcut_lim, ierr)
     315              :          if (ierr /= 0) return
     316              :       end subroutine net_set_logTcut
     317              : 
     318              : 
     319            0 :       subroutine net_set_eps_nuc_cancel(handle, logT_lo_eps_nuc_cancel, logT_hi_eps_nuc_cancel, ierr)
     320              :          use net_def, only: do_net_set_eps_nuc_cancel
     321              :          integer, intent(in) :: handle
     322              :          real(dp), intent(in) :: logT_lo_eps_nuc_cancel, logT_hi_eps_nuc_cancel
     323              :          integer, intent(out) :: ierr
     324              :          ierr = 0
     325            0 :          call do_net_set_eps_nuc_cancel(handle, logT_lo_eps_nuc_cancel, logT_hi_eps_nuc_cancel, ierr)
     326              :          if (ierr /= 0) return
     327              :       end subroutine net_set_eps_nuc_cancel
     328              : 
     329              : 
     330              :       ! call this after you have finished defining the net
     331           19 :       subroutine net_setup_tables(handle, cache_suffix, ierr)
     332              :          ! This routine fills in a Net_General_Info structure.
     333              :          use net_initialize, only : alloc_net_general_info
     334              :          use rates_lib, only: read_raw_rates_records
     335              :          use net_def, only: Net_General_Info, get_net_ptr
     336              :          integer, intent(in) :: handle
     337              :          character (len=*), intent(in) :: cache_suffix
     338              :          integer, intent(out) :: ierr
     339              :          type (Net_General_Info), pointer :: g
     340              :          ierr = 0
     341           19 :          call read_raw_rates_records(ierr)
     342           19 :          if (ierr /= 0) then
     343            0 :             write(*,*) 'read_raw_rates_records failed in net_setup_tables'
     344            0 :             return
     345              :          end if
     346           19 :          call alloc_net_general_info(handle, cache_suffix, ierr)
     347           19 :          if (ierr /= 0) then
     348            0 :             write(*,*) 'alloc_net_general_info failed in net_setup_tables'
     349            0 :             return
     350              :          end if
     351           19 :       end subroutine net_setup_tables
     352              : 
     353              : 
     354              :       ! general info about the net
     355              : 
     356              : 
     357            1 :       integer function net_num_isos(handle, ierr)  ! total number in current net
     358           19 :          use net_def, only: Net_General_Info, get_net_ptr
     359              :          integer, intent(in) :: handle
     360              :          integer, intent(out) :: ierr
     361              :          type (Net_General_Info), pointer :: g
     362            1 :          net_num_isos = 0
     363            1 :          call get_net_ptr(handle, g, ierr)
     364            1 :          if (ierr /= 0) then
     365            0 :             write(*,*) 'invalid handle for net_num_isos -- did you call alloc_net_handle?'
     366            0 :             return
     367              :          end if
     368            1 :          net_num_isos = g% num_isos
     369            1 :       end function net_num_isos
     370              : 
     371            1 :       integer function net_num_reactions(handle, ierr)  ! total number of rates for net
     372              :          use net_def, only: Net_General_Info, get_net_ptr
     373              :          integer, intent(in) :: handle
     374              :          integer, intent(out) :: ierr
     375              :          type (Net_General_Info), pointer :: g
     376            1 :          net_num_reactions = 0
     377            1 :          call get_net_ptr(handle, g, ierr)
     378            1 :          if (ierr /= 0) then
     379            0 :             write(*,*) 'invalid handle for net_num_reactions -- did you call alloc_net_handle?'
     380            0 :             return
     381              :          end if
     382            1 :          net_num_reactions = g% num_reactions
     383            1 :       end function net_num_reactions
     384              : 
     385           32 :       subroutine get_chem_id_table(handle, num_isos, chem_id, ierr)
     386              :          use net_def, only: Net_General_Info, get_net_ptr
     387              :          integer, intent(in) :: handle, num_isos  ! num_isos must be number of isos in current net
     388              :          integer, intent(out) :: chem_id(num_isos)  ! maps net iso number to chem id
     389              :             ! index from 1 to num_isos in current net
     390              :             ! value is between 1 and num_chem_isos
     391              :          integer, intent(out) :: ierr
     392              :          type (Net_General_Info), pointer :: g
     393              :          ierr = 0
     394           32 :          call get_net_ptr(handle, g, ierr)
     395           32 :          if (ierr /= 0) then
     396            0 :             write(*,*) 'invalid handle for get_chem_id_table -- did you call alloc_net_handle?'
     397            0 :             return
     398              :          end if
     399           32 :          if (num_isos /= g% num_isos) then
     400            0 :             ierr = -1
     401            0 :             return
     402              :          end if
     403          580 :          chem_id(1:num_isos) = g% chem_id(1:num_isos)
     404           32 :          ierr = 0
     405              :       end subroutine get_chem_id_table
     406              : 
     407            1 :       subroutine get_chem_id_table_ptr(handle, chem_id_ptr, ierr)
     408              :          use net_def, only: Net_General_Info, get_net_ptr
     409              :          integer, intent(in) :: handle
     410              :          integer, pointer :: chem_id_ptr(:)  ! maps net iso number to chem id
     411              :             ! index from 1 to num_isos in current net
     412              :             ! value is between 1 and num_chem_isos
     413              :          integer, intent(out) :: ierr
     414              :          type (Net_General_Info), pointer :: g
     415              :          ierr = 0
     416            1 :          call get_net_ptr(handle, g, ierr)
     417            1 :          if (ierr /= 0) then
     418            0 :             write(*,*) 'invalid handle for get_chem_id_table_ptr -- did you call alloc_net_handle?'
     419            0 :             return
     420              :          end if
     421            1 :          chem_id_ptr => g% chem_id
     422              :       end subroutine get_chem_id_table_ptr
     423              : 
     424           18 :       subroutine get_net_iso_table(handle, net_iso_table, ierr)
     425              :          use net_def, only: Net_General_Info, get_net_ptr
     426              :          integer, intent(in) :: handle
     427              :          integer, intent(out) :: net_iso_table(num_chem_isos)  ! maps chem id to net iso number
     428              :             ! index from 1 to num_chem_isos
     429              :             ! value is 0 if the iso is not in the current net
     430              :             ! else is value between 1 and num_isos in current net
     431              :          integer, intent(out) :: ierr
     432              :          type (Net_General_Info), pointer :: g
     433              :          ierr = 0
     434           18 :          call get_net_ptr(handle, g, ierr)
     435           18 :          if (ierr /= 0) then
     436            0 :             write(*,*) 'invalid handle for get_net_iso_table -- did you call alloc_net_handle?'
     437            0 :             return
     438              :          end if
     439       141426 :          net_iso_table(1:num_chem_isos) = g% net_iso(1:num_chem_isos)
     440           18 :          ierr = 0
     441              :       end subroutine get_net_iso_table
     442              : 
     443            1 :       subroutine get_net_iso_table_ptr(handle, net_iso_ptr, ierr)
     444              :          use net_def, only: Net_General_Info, get_net_ptr
     445              :          integer, intent(in) :: handle
     446              :          integer, pointer :: net_iso_ptr(:)  ! maps chem id to net iso number
     447              :             ! index from 1 to num_chem_isos
     448              :             ! value is 0 if the iso is not in the current net
     449              :             ! else is value between 1 and num_isos in current net
     450              :          integer, intent(out) :: ierr
     451              :          type (Net_General_Info), pointer :: g
     452              :          ierr = 0
     453            1 :          call get_net_ptr(handle, g, ierr)
     454            1 :          if (ierr /= 0) then
     455            0 :             write(*,*) 'invalid handle for get_net_iso_table_ptr -- did you call alloc_net_handle?'
     456            0 :             return
     457              :          end if
     458            1 :          net_iso_ptr => g% net_iso
     459            1 :          ierr = 0
     460              :       end subroutine get_net_iso_table_ptr
     461              : 
     462           18 :       subroutine get_reaction_id_table(handle, num_reactions, reaction_id, ierr)
     463              :          use net_def, only: Net_General_Info, get_net_ptr
     464              :          integer, intent(in) :: handle, num_reactions
     465              :             ! num_reactions must be number of reactions in current net
     466              :          integer, intent(out) :: reaction_id(num_reactions)
     467              :             ! maps net reaction number to reaction id
     468              :             ! index from 1 to num_reactions in current net
     469              :             ! value is between 1 and num_reactions
     470              :          integer, intent(out) :: ierr
     471              :          type (Net_General_Info), pointer :: g
     472              :          ierr = 0
     473           18 :          call get_net_ptr(handle, g, ierr)
     474           18 :          if (ierr /= 0) then
     475            0 :             write(*,*) 'invalid handle for get_reaction_id_table -- did you call alloc_net_handle?'
     476            0 :             return
     477              :          end if
     478           18 :          if (num_reactions /= g% num_reactions) then
     479            0 :             ierr = -1
     480            0 :             return
     481              :          end if
     482              : 
     483         1298 :          reaction_id(1:num_reactions) = g% reaction_id(1:num_reactions)
     484           18 :          ierr = 0
     485              :       end subroutine get_reaction_id_table
     486              : 
     487            0 :       subroutine get_reaction_id_table_ptr(handle, reaction_id_ptr, ierr)
     488              :          use net_def, only: Net_General_Info, get_net_ptr
     489              :          integer, intent(in) :: handle
     490              :          integer, pointer :: reaction_id_ptr(:)  ! maps net reaction number to reaction id
     491              :             ! index from 1 to num_reactions in current net
     492              :             ! value is between 1 and rates_reaction_id_max
     493              :          integer, intent(out) :: ierr
     494              :          type (Net_General_Info), pointer :: g
     495              :          ierr = 0
     496            0 :          call get_net_ptr(handle, g, ierr)
     497            0 :          if (ierr /= 0) then
     498            0 :             write(*,*) 'invalid handle for get_reaction_id_table_ptr -- did you call alloc_net_handle?'
     499            0 :             return
     500              :          end if
     501            0 :          reaction_id_ptr => g% reaction_id
     502              :       end subroutine get_reaction_id_table_ptr
     503              : 
     504           28 :       subroutine get_net_reaction_table(handle, net_reaction_table, ierr)
     505              :          use net_def, only: Net_General_Info, get_net_ptr
     506              :          use rates_def, only: rates_reaction_id_max
     507              :          integer, intent(in) :: handle
     508              :          integer, intent(out) :: net_reaction_table(rates_reaction_id_max)
     509              :             ! maps reaction id to net reaction number
     510              :             ! index from 1 to rates_reaction_id_max
     511              :             ! value is 0 if the reaction is not in the current net
     512              :             ! else is value between 1 and rates_reaction_id_max in current net
     513              :          integer, intent(out) :: ierr
     514              :          type (Net_General_Info), pointer :: g
     515              :          ierr = 0
     516           14 :          call get_net_ptr(handle, g, ierr)
     517           14 :          if (ierr /= 0) then
     518              :             write(*,*) &
     519            0 :                'invalid handle for get_net_reaction_table -- did you call alloc_net_handle?'
     520              :             return
     521              :          end if
     522         4524 :          net_reaction_table(1:rates_reaction_id_max) = g% net_reaction(1:rates_reaction_id_max)
     523           14 :          ierr = 0
     524           14 :       end subroutine get_net_reaction_table
     525              : 
     526            4 :       subroutine get_net_reaction_table_ptr(handle, net_reaction_ptr, ierr)
     527           14 :          use net_def, only: Net_General_Info, get_net_ptr
     528              :          integer, intent(in) :: handle
     529              :          integer, pointer :: net_reaction_ptr(:)
     530              :             ! maps reaction id to net reaction number
     531              :             ! index from 1 to num_reactions
     532              :             ! value is 0 if the reaction is not in the current net
     533              :             ! else is value between 1 and num_reactions in current net
     534              :          integer, intent(out) :: ierr
     535              :          type (Net_General_Info), pointer :: g
     536              :          ierr = 0
     537            4 :          call get_net_ptr(handle, g, ierr)
     538            4 :          if (ierr /= 0) then
     539              :             write(*,*) &
     540            0 :                'invalid handle for get_net_reaction_table_ptr -- did you call alloc_net_handle?'
     541            0 :             return
     542              :          end if
     543            4 :          net_reaction_ptr => g% net_reaction
     544            4 :          ierr = 0
     545              :       end subroutine get_net_reaction_table_ptr
     546              : 
     547              : 
     548              :       ! net evaluation routines
     549              : 
     550        80008 :       subroutine net_get( &
     551              :             handle, just_dxdt, n, num_isos, num_reactions,  &
     552        80008 :             x, temp, log10temp, rho, log10rho,  &
     553              :             abar, zbar, z2bar, ye, eta, d_eta_dlnT, d_eta_dlnRho, &
     554              :             rate_factors, weak_rate_factor, &
     555              :             reaction_Qs, reaction_neuQs, &
     556        80008 :             eps_nuc, d_eps_nuc_dRho, d_eps_nuc_dT, d_eps_nuc_dx,  &
     557        80008 :             dxdt, d_dxdt_dRho, d_dxdt_dT, d_dxdt_dx,  &
     558              :             screening_mode,  &
     559        80008 :             eps_nuc_categories, eps_neu_total, &
     560              :             ierr)
     561              :          use chem_def, only: num_categories
     562              :          use net_eval, only: eval_net
     563              :          use net_def, only: Net_General_Info, Net_Info, get_net_ptr
     564              : 
     565              :          use rates_def, only: num_rvs
     566              : 
     567              :          ! provide T or logT or both (the code needs both, so pass 'em if you've got 'em!)
     568              :          ! same for Rho and logRho
     569              : 
     570              :          integer, intent(in) :: handle
     571              :          logical, intent(in) :: just_dxdt
     572              :          type (Net_Info) :: n
     573              :          integer, intent(in) :: num_isos
     574              :          integer, intent(in) :: num_reactions
     575              :          real(dp), intent(in)  :: x(:)  ! (num_isos)
     576              :          real(dp), intent(in)  :: temp, log10temp  ! log10 of temp
     577              :          real(dp), intent(in)  :: rho, log10rho  ! log10 of rho
     578              :          real(dp), intent(in)  :: abar  ! mean number of nucleons per nucleus
     579              :          real(dp), intent(in)  :: zbar  ! mean charge per nucleus
     580              :          real(dp), intent(in)  :: z2bar  ! mean charge squared per nucleus
     581              :          real(dp), intent(in)  :: ye
     582              :             ! mean number free electrons per nucleon, assuming complete ionization
     583              :             ! d_dxdt_dx(i, j) is d_dxdt(i)_dx(j),
     584              :             ! i.e., partial derivative of rate for i'th isotope wrt j'th isotope abundance
     585              :          real(dp), intent(in)  :: eta, d_eta_dlnT, d_eta_dlnRho  ! electron degeneracy from eos.
     586              :             ! this arg is only used for prot(e-nu)neut and neut(e+nu)prot.
     587              :             ! if your net doesn't include those, you can safely ignore this arg.
     588              :          real(dp), intent(in), pointer :: rate_factors(:)  ! (num_reactions)
     589              :             ! when rates are calculated, they are multiplied by the
     590              :             ! corresponding values in this array.
     591              :             ! rate_factors array is indexed by reaction number.
     592              :             ! use net_reaction_table to map reaction id to reaction number.
     593              :          real(dp), intent(in) :: weak_rate_factor
     594              :          real(dp), pointer, intent(in) :: reaction_Qs(:)  ! (rates_reaction_id_max)
     595              :          real(dp), pointer, intent(in) :: reaction_neuQs(:)  ! (rates_reaction_id_max)
     596              : 
     597              :          real(dp), intent(out) :: eps_nuc  ! ergs/g/s from burning after including losses from reaction neutrinos
     598              :          real(dp), intent(out) :: d_eps_nuc_dT
     599              :          real(dp), intent(out) :: d_eps_nuc_dRho
     600              :          real(dp), intent(inout) :: d_eps_nuc_dx(:)  ! (num_isos)
     601              :             ! partial derivatives wrt mass fractions
     602              : 
     603              :          real(dp), intent(inout) :: dxdt(:)  ! (num_isos)
     604              :             ! rate of change of mass fractions caused by nuclear reactions
     605              :          real(dp), intent(inout) :: d_dxdt_dRho(:)  ! (num_isos)
     606              :          real(dp), intent(inout) :: d_dxdt_dT(:)  ! (num_isos)
     607              :          real(dp), intent(inout) :: d_dxdt_dx(:,:)  ! (num_isos, num_isos)
     608              :             ! partial derivatives of rates wrt mass fractions
     609              : 
     610              :          real(dp), intent(inout) :: eps_nuc_categories(:)  ! (num_categories)
     611              :             ! eps_nuc subtotals for each reaction category
     612              : 
     613              :          real(dp), intent(out) :: eps_neu_total  ! ergs/g/s neutrinos from weak reactions
     614              : 
     615              :          integer, intent(in) :: screening_mode
     616              : 
     617              :          integer, intent(out) :: ierr  ! 0 means okay
     618              : 
     619              :          integer(i8) :: time0, time1
     620              :          type (Net_General_Info), pointer :: g
     621        80008 :          real(dp), pointer, dimension(:) :: actual_Qs, actual_neuQs
     622        80008 :          logical, pointer :: from_weaklib(:)  ! ignore if null
     623              :          logical, parameter :: symbolic = .false.
     624              :          logical, parameter :: rates_only = .false.
     625        80008 :          actual_Qs => null()
     626        80008 :          actual_neuQs => null()
     627        80008 :          from_weaklib => null()
     628              : 
     629              :          ierr = 0
     630        80008 :          call get_net_ptr(handle, g, ierr)
     631        80008 :          if (ierr /= 0) then
     632            0 :             write(*,*) 'invalid handle for net_get -- did you call alloc_net_handle?'
     633              :             return
     634              :          end if
     635              : 
     636        80008 :          if (g% doing_timing) then
     637            0 :             call system_clock(time0)
     638              :          else
     639              :             time0 = 0
     640              :          end if
     641              : 
     642              :          call eval_net( &
     643              :                n, g, rates_only, just_dxdt, num_isos, num_reactions, g% num_wk_reactions, &
     644              :                x, temp, log10temp, rho, log10rho,  &
     645              :                abar, zbar, z2bar, ye, eta, d_eta_dlnT, d_eta_dlnRho, &
     646              :                rate_factors, weak_rate_factor, &
     647              :                reaction_Qs, reaction_neuQs, &
     648              :                eps_nuc, d_eps_nuc_dRho, d_eps_nuc_dT, d_eps_nuc_dx,  &
     649              :                dxdt, d_dxdt_dRho, d_dxdt_dT, d_dxdt_dx,  &
     650              :                screening_mode,  &
     651              :                eps_nuc_categories, eps_neu_total, &
     652              :                actual_Qs, actual_neuQs, from_weaklib, symbolic, &
     653        80008 :                ierr)
     654        80008 :          if (g% doing_timing) then
     655            0 :             call system_clock(time1)
     656            0 :             g% clock_net_get = g% clock_net_get + (time1 - time0)
     657              :          end if
     658              : 
     659       160016 :       end subroutine net_get
     660              : 
     661            0 :       subroutine net_get_rates_only( &
     662              :             handle, n, num_isos, num_reactions,  &
     663            0 :             x, temp, log10temp, rho, log10rho,  &
     664              :             abar, zbar, z2bar, ye, eta, d_eta_dlnT, d_eta_dlnRho, &
     665              :             rate_factors, weak_rate_factor, &
     666              :             reaction_Qs, reaction_neuQs, &
     667              :             screening_mode,  &
     668              :             ierr)
     669        80008 :          use chem_def, only: num_categories
     670              :          use net_eval, only: eval_net
     671              :          use net_def, only: Net_General_Info, Net_Info, get_net_ptr
     672              :          use rates_def, only: num_rvs
     673              : 
     674              :          ! provide T or logT or both (the code needs both, so pass 'em if you've got 'em!)
     675              :          ! same for Rho and logRho
     676              : 
     677              :          integer, intent(in) :: handle
     678              :          type (Net_Info) :: n
     679              :          integer, intent(in) :: num_isos
     680              :          integer, intent(in) :: num_reactions
     681              :          real(dp), intent(in)  :: x(:)  ! (num_isos)
     682              :          real(dp), intent(in)  :: temp, log10temp  ! log10 of temp
     683              :          real(dp), intent(in)  :: rho, log10rho  ! log10 of rho
     684              :          real(dp), intent(in)  :: abar  ! mean number of nucleons per nucleus
     685              :          real(dp), intent(in)  :: zbar  ! mean charge per nucleus
     686              :          real(dp), intent(in)  :: z2bar  ! mean charge squared per nucleus
     687              :          real(dp), intent(in)  :: ye
     688              :             ! mean number free electrons per nucleon, assuming complete ionization
     689              :             ! d_dxdt_dx(i, j) is d_dxdt(i)_dx(j),
     690              :             ! i.e., partial derivative of rate for i'th isotope wrt j'th isotope abundance
     691              :          real(dp), intent(in)  :: eta, d_eta_dlnT, d_eta_dlnRho  ! electron degeneracy from eos.
     692              :             ! this arg is only used for prot(e-nu)neut and neut(e+nu)prot.
     693              :             ! if your net doesn't include those, you can safely ignore this arg.
     694              :          real(dp), intent(in), pointer :: rate_factors(:)  ! (num_reactions)
     695              :             ! when rates are calculated, they are multiplied by the
     696              :             ! corresponding values in this array.
     697              :             ! rate_factors array is indexed by reaction number.
     698              :             ! use net_reaction_table to map reaction id to reaction number.
     699              :          real(dp), intent(in) :: weak_rate_factor
     700              :          real(dp), pointer, intent(in) :: reaction_Qs(:)  ! (rates_reaction_id_max)
     701              :          real(dp), pointer, intent(in) :: reaction_neuQs(:)  ! (rates_reaction_id_max)
     702              : 
     703              :          ! rate_raw and rate_screened are described in the declaration of the Net_Info derived type
     704              : 
     705              :          integer, intent(in) :: screening_mode
     706              : 
     707              :          integer, intent(out) :: ierr  ! 0 means okay
     708              : 
     709              :          integer(i8) :: time0, time1
     710              :          type (Net_General_Info), pointer :: g
     711            0 :          real(dp), pointer, dimension(:) :: actual_Qs, actual_neuQs
     712            0 :          logical, pointer :: from_weaklib(:)  ! ignore if null
     713              :          logical, parameter :: symbolic = .false.
     714              : 
     715            0 :          real(dp) :: eps_nuc, d_eps_nuc_dT, d_eps_nuc_dRho, eps_neu_total
     716              : 
     717              :          real(dp), target :: empty_array1(0), empty_array2(0,0)
     718              :          real(dp), pointer, dimension(:) :: &
     719              :             d_eps_nuc_dx, dxdt, d_dxdt_dRho, d_dxdt_dT, eps_nuc_categories
     720              :          real(dp), pointer, dimension(:,:) :: d_dxdt_dx
     721              :          logical, parameter :: rates_only = .true.
     722              :          logical, parameter :: just_dxdt = .true.
     723              : 
     724            0 :          d_eps_nuc_dx => empty_array1
     725            0 :          dxdt => empty_array1
     726            0 :          d_dxdt_dRho => empty_array1
     727            0 :          d_dxdt_dT => empty_array1
     728              : 
     729            0 :          d_dxdt_dx => empty_array2
     730            0 :          eps_nuc_categories => empty_array1
     731              : 
     732            0 :          actual_Qs => null()
     733            0 :          actual_neuQs => null()
     734            0 :          from_weaklib => null()
     735              : 
     736              :          ierr = 0
     737            0 :          call get_net_ptr(handle, g, ierr)
     738            0 :          if (ierr /= 0) then
     739            0 :             write(*,*) 'invalid handle for net_get -- did you call alloc_net_handle?'
     740              :             return
     741              :          end if
     742              : 
     743            0 :          if (g% doing_timing) then
     744            0 :             call system_clock(time0)
     745              :          else
     746              :             time0 = 0
     747              :          end if
     748              : 
     749              :          call eval_net( &
     750              :                n, g, rates_only, just_dxdt, num_isos, num_reactions, g% num_wk_reactions, &
     751              :                x, temp, log10temp, rho, log10rho,  &
     752              :                abar, zbar, z2bar, ye, eta, d_eta_dlnT, d_eta_dlnRho, &
     753              :                rate_factors, weak_rate_factor, &
     754              :                reaction_Qs, reaction_neuQs, &
     755              :                eps_nuc, d_eps_nuc_dRho, d_eps_nuc_dT, d_eps_nuc_dx,  &
     756              :                dxdt, d_dxdt_dRho, d_dxdt_dT, d_dxdt_dx,  &
     757              :                screening_mode,  &
     758              :                eps_nuc_categories, eps_neu_total, &
     759              :                actual_Qs, actual_neuQs, from_weaklib, symbolic, &
     760            0 :                ierr)
     761            0 :          if (g% doing_timing) then
     762            0 :             call system_clock(time1)
     763            0 :             g% clock_net_get = g% clock_net_get + (time1 - time0)
     764              :          end if
     765              : 
     766            0 :       end subroutine net_get_rates_only
     767              : 
     768              : 
     769              :       ! this sets d_dxdt_dx to 1 in locations where can have a nonzero partial
     770              :       ! it doesn't set other things such as eps_nuc or rates.
     771              :       ! takes the same set of args as net_get even though doesn't use them all.
     772            0 :       subroutine net_get_symbolic_d_dxdt_dx( &
     773              :             handle, n, num_isos, num_reactions,  &
     774            0 :             x, temp, log10temp, rho, log10rho, &
     775              :             abar, zbar, z2bar, ye, eta, d_eta_dlnT, d_eta_dlnRho, &
     776              :             rate_factors, weak_rate_factor, &
     777              :             reaction_Qs, reaction_neuQs, &
     778            0 :             eps_nuc, d_eps_nuc_dRho, d_eps_nuc_dT, d_eps_nuc_dx,  &
     779            0 :             dxdt, d_dxdt_dRho, d_dxdt_dT, d_dxdt_dx,  &
     780              :             screening_mode,  &
     781            0 :             eps_nuc_categories, eps_neu_total, &
     782              :             ierr)
     783            0 :          use chem_def, only: num_categories
     784              :          use net_eval, only: eval_net
     785              :          use net_def, only: Net_General_Info, Net_Info, get_net_ptr
     786              :          use rates_def, only: num_rvs
     787              : 
     788              :          integer, intent(in) :: handle
     789              :          type (Net_Info)  :: n
     790              :          integer, intent(in) :: num_isos
     791              :          integer, intent(in) :: num_reactions
     792              :          real(dp), intent(in)  :: x(:)  ! (num_isos)
     793              :          real(dp), intent(in)  :: temp, log10temp  ! log10 of temp
     794              :          real(dp), intent(in)  :: rho, log10rho  ! log10 of rho
     795              :          real(dp), intent(in)  :: abar  ! mean number of nucleons per nucleus
     796              :          real(dp), intent(in)  :: zbar  ! mean charge per nucleus
     797              :          real(dp), intent(in)  :: z2bar  ! mean charge squared per nucleus
     798              :          real(dp), intent(in)  :: ye
     799              :             ! mean number free electrons per nucleon, assuming complete ionization
     800              :             ! d_dxdt_dx(i, j) is d_dxdt(i)_dx(j),
     801              :             ! i.e., partial derivative of rate for i'th isotope wrt j'th isotope abundance
     802              :          real(dp), intent(in)  :: eta, d_eta_dlnT, d_eta_dlnRho  ! electron degeneracy from eos.
     803              :             ! this arg is only used for prot(e-nu)neut and neut(e+nu)prot.
     804              :             ! if your net doesn't include those, you can safely ignore this arg.
     805              :          real(dp), intent(in), pointer :: rate_factors(:)  ! (num_reactions)
     806              :             ! when rates are calculated, they are multiplied by the
     807              :             ! corresponding values in this array.
     808              :             ! rate_factors array is indexed by reaction number.
     809              :             ! use net_reaction_table to map reaction id to reaction number.
     810              :          real(dp), intent(in) :: weak_rate_factor
     811              :          real(dp), pointer, intent(in) :: reaction_Qs(:)  ! (rates_reaction_id_max)
     812              :          real(dp), pointer, intent(in) :: reaction_neuQs(:)  ! (rates_reaction_id_max)
     813              : 
     814              :          real(dp), intent(out) :: eps_nuc  ! ergs/g/s from burning after including reaction neutrinos
     815              :          real(dp), intent(out) :: d_eps_nuc_dT
     816              :          real(dp), intent(out) :: d_eps_nuc_dRho
     817              :          real(dp), intent(inout) :: d_eps_nuc_dx(:)  ! (num_isos)
     818              :             ! partial derivatives wrt mass fractions
     819              : 
     820              :          real(dp), intent(inout) :: dxdt(:)  ! (num_isos)
     821              :             ! rate of change of mass fractions caused by nuclear reactions
     822              :          real(dp), intent(inout) :: d_dxdt_dRho(:)  ! (num_isos)
     823              :          real(dp), intent(inout) :: d_dxdt_dT(:)  ! (num_isos)
     824              :          real(dp), intent(inout) :: d_dxdt_dx(:,:)  ! (num_isos, num_isos)
     825              :             ! partial derivatives of rates wrt mass fractions
     826              : 
     827              :          real(dp), intent(inout) :: eps_nuc_categories(:)  ! (num_categories)
     828              :             ! eps_nuc subtotals for each reaction category
     829              : 
     830              :          real(dp), intent(out) :: eps_neu_total  ! ergs/g/s neutrinos from weak reactions
     831              : 
     832              :          ! rate_raw and rate_screened are described in the declaration of the Net_Info derived type
     833              : 
     834              :          integer, intent(in) :: screening_mode  ! Selects which screening mode to use, see rates_def for definition
     835              : 
     836              :          integer, intent(out) :: ierr
     837              :             ! ierr = 0 means AOK
     838              :             ! ierr = -1 means mass fractions don't add to something very close to 1.0
     839              :             ! ierr = -2 means neither T nor logT were provided
     840              :             ! ierr = -3 means neither Rho nor logRho were provided
     841              : 
     842              :          type (Net_General_Info), pointer :: g
     843            0 :          real(dp), pointer, dimension(:) :: actual_Qs, actual_neuQs
     844            0 :          logical, pointer :: from_weaklib(:)  ! ignore if null
     845              :          logical, parameter :: symbolic = .true.
     846              :          integer :: num_rates_reduced
     847              :          real(dp) :: max_old_rate_div_new_rate
     848              :          logical, parameter :: rates_only = .false.
     849              :          logical, parameter :: just_dxdt = .false.
     850              : 
     851            0 :          actual_Qs => null()
     852            0 :          actual_neuQs => null()
     853            0 :          from_weaklib => null()
     854              : 
     855              :          ierr = 0
     856            0 :          call get_net_ptr(handle, g, ierr)
     857            0 :          if (ierr /= 0) then
     858              :             write(*,'(a)')  &
     859            0 :                'invalid handle for net_get_symbolic_d_dxdt_dx -- did you call alloc_net_handle?'
     860              :             return
     861              :          end if
     862              : 
     863              :          call eval_net( &
     864              :             n, g, rates_only, just_dxdt, num_isos, num_reactions, g% num_wk_reactions, &
     865              :             x, temp, log10temp, rho, log10rho,  &
     866              :             abar, zbar, z2bar, ye, eta, d_eta_dlnT, d_eta_dlnRho, &
     867              :             rate_factors, weak_rate_factor, &
     868              :             reaction_Qs, reaction_neuQs, &
     869              :             eps_nuc, d_eps_nuc_dRho, d_eps_nuc_dT, d_eps_nuc_dx,  &
     870              :             dxdt, d_dxdt_dRho, d_dxdt_dT, d_dxdt_dx,  &
     871              :             screening_mode,  &
     872              :             eps_nuc_categories, eps_neu_total, &
     873              :             actual_Qs, actual_neuQs, from_weaklib, symbolic, &
     874            0 :             ierr)
     875              : 
     876            0 :       end subroutine net_get_symbolic_d_dxdt_dx
     877              : 
     878          896 :       subroutine net_get_with_Qs( &
     879              :             handle, just_dxdt, n, num_isos, num_reactions,  &
     880          896 :             x, temp, log10temp, rho, log10rho,  &
     881              :             abar, zbar, z2bar, ye, eta, d_eta_dlnT, d_eta_dlnRho, &
     882              :             rate_factors, weak_rate_factor, &
     883              :             reaction_Qs, reaction_neuQs, &
     884          896 :             eps_nuc, d_eps_nuc_dRho, d_eps_nuc_dT, d_eps_nuc_dx,  &
     885          896 :             dxdt, d_dxdt_dRho, d_dxdt_dT, d_dxdt_dx,  &
     886              :             screening_mode,  &
     887          896 :             eps_nuc_categories, eps_neu_total, &
     888              :             actual_Qs, actual_neuQs, from_weaklib, &
     889              :             ierr)
     890            0 :          use chem_def, only: num_categories
     891              :          use net_eval, only: eval_net
     892              :          use net_def, only: Net_General_Info, Net_Info, get_net_ptr
     893              :          use rates_def, only: num_rvs
     894              :          integer, intent(in) :: handle
     895              :          logical, intent(in) :: just_dxdt
     896              :          type (Net_Info) :: n
     897              :          integer, intent(in) :: num_isos
     898              :          integer, intent(in) :: num_reactions
     899              :          real(dp), intent(in)  :: x(:)  ! (num_isos)
     900              :          real(dp), intent(in)  :: temp, log10temp  ! log10 of temp
     901              :          real(dp), intent(in)  :: rho, log10rho  ! log10 of rho
     902              :          real(dp), intent(in)  :: abar  ! mean number of nucleons per nucleus
     903              :          real(dp), intent(in)  :: zbar  ! mean charge per nucleus
     904              :          real(dp), intent(in)  :: z2bar  ! mean charge squared per nucleus
     905              :          real(dp), intent(in)  :: ye
     906              :          real(dp), intent(in)  :: eta, d_eta_dlnT, d_eta_dlnRho  ! electron degeneracy from eos.
     907              :          real(dp), intent(in), pointer :: rate_factors(:)  ! (num_reactions)
     908              :          real(dp), intent(in) :: weak_rate_factor
     909              :          real(dp), pointer, intent(in) :: reaction_Qs(:)  ! (rates_reaction_id_max)
     910              :          real(dp), pointer, intent(in) :: reaction_neuQs(:)  ! (rates_reaction_id_max)
     911              :          real(dp), intent(out) :: eps_nuc  ! ergs/g/s from burning after including reaction neutrinos
     912              :          real(dp), intent(out) :: d_eps_nuc_dT
     913              :          real(dp), intent(out) :: d_eps_nuc_dRho
     914              :          real(dp), intent(inout) :: d_eps_nuc_dx(:)  ! (num_isos)
     915              :          real(dp), intent(inout) :: dxdt(:)  ! (num_isos)
     916              :          real(dp), intent(inout) :: d_dxdt_dRho(:)  ! (num_isos)
     917              :          real(dp), intent(inout) :: d_dxdt_dT(:)  ! (num_isos)
     918              :          real(dp), intent(inout) :: d_dxdt_dx(:,:)  ! (num_isos, num_isos)
     919              :          real(dp), intent(inout) :: eps_nuc_categories(:)  ! (num_categories)
     920              :          real(dp), intent(out) :: eps_neu_total  ! ergs/g/s neutrinos from weak reactions
     921              :          integer, intent(in) :: screening_mode
     922              :          real(dp), pointer, dimension(:) :: actual_Qs, actual_neuQs  ! ignore if null  (num_reactions)
     923              :          logical, pointer :: from_weaklib(:)  ! ignore if null
     924              :          integer, intent(out) :: ierr
     925              : 
     926              :          logical, parameter :: rates_only = .false.
     927              :          logical, parameter :: symbolic = .false.
     928              :          integer(i8) :: time0, time1
     929              :          type (Net_General_Info), pointer :: g
     930              : 
     931              :          ierr = 0
     932          896 :          call get_net_ptr(handle, g, ierr)
     933          896 :          if (ierr /= 0) then
     934            0 :             write(*,*) 'invalid handle for net_get_with_Qs -- did you call alloc_net_handle?'
     935              :             return
     936              :          end if
     937              : 
     938          896 :          if (g% doing_timing) then
     939            0 :             call system_clock(time0)
     940              :          else
     941              :             time0 = 0
     942              :          end if
     943              : 
     944              :          call eval_net( &
     945              :             n, g, rates_only, just_dxdt, num_isos, num_reactions, g% num_wk_reactions, &
     946              :             x, temp, log10temp, rho, log10rho,  &
     947              :             abar, zbar, z2bar, ye, eta, d_eta_dlnT, d_eta_dlnRho, &
     948              :             rate_factors, weak_rate_factor, &
     949              :             reaction_Qs, reaction_neuQs, &
     950              :             eps_nuc, d_eps_nuc_dRho, d_eps_nuc_dT, d_eps_nuc_dx,  &
     951              :             dxdt, d_dxdt_dRho, d_dxdt_dT, d_dxdt_dx,  &
     952              :             screening_mode,  &
     953              :             eps_nuc_categories, eps_neu_total, &
     954              :             actual_Qs, actual_neuQs, from_weaklib, symbolic, &
     955          896 :             ierr)
     956          896 :          if (g% doing_timing) then
     957            0 :             call system_clock(time1)
     958            0 :             g% clock_net_get = g% clock_net_get + (time1 - time0)
     959              :          end if
     960              : 
     961          896 :       end subroutine net_get_with_Qs
     962              : 
     963              :       ! a 1-zone integrator for nets -- for given temperature and density as functions of time
     964            2 :       subroutine net_1_zone_burn( &
     965            2 :             net_handle, eos_handle, num_isos, num_reactions, t_start, t_end, starting_x, &
     966              :             num_times_for_interpolation, times, log10Ts_f1, log10Rhos_f1, etas_f1, &
     967              :             dxdt_source_term, rate_factors, &
     968              :             weak_rate_factor, reaction_Qs, reaction_neuQs, &
     969              :             screening_mode, &
     970              :             stptry, max_steps, eps, odescal, &
     971              :             use_pivoting, trace, dbg, burner_finish_substep, &
     972              :             ! results
     973            2 :             ending_x, eps_nuc_categories, avg_eps_nuc, eps_neu_total, &
     974              :             nfcn, njac, nstep, naccpt, nrejct, ierr)
     975          896 :          use net_burn, only: burn_1_zone
     976              :          use net_def
     977              :          use chem_def, only: num_categories
     978              : 
     979              :          integer, intent(in) :: net_handle, eos_handle
     980              :          integer, intent(in) :: num_isos
     981              :          integer, intent(in) :: num_reactions
     982              :          real(dp), intent(in) :: t_start, t_end, starting_x(:)  ! (num_isos)
     983              : 
     984              :          integer, intent(in) :: num_times_for_interpolation
     985              :             ! ending time is times(num_times); starting time is 0
     986              :          real(dp), pointer, intent(in) :: times(:)  ! (num_times)
     987              :          real(dp), pointer, intent(in) :: log10Ts_f1(:)  ! =(4,numtimes) interpolant for log10T(time)
     988              :          real(dp), pointer, intent(in) :: log10Rhos_f1(:)  ! =(4,numtimes) interpolant for log10Rho(time)
     989              :          real(dp), pointer, intent(in) :: etas_f1(:)  ! =(4,numtimes) interpolant for eta(time)
     990              :          real(dp), pointer, intent(in) :: dxdt_source_term(:)  ! (num_isos)  or null if no source term.
     991              :          real(dp), intent(in), pointer :: rate_factors(:)  ! (num_reactions)
     992              :          real(dp), intent(in) :: weak_rate_factor
     993              :          real(dp), pointer, intent(in) :: reaction_Qs(:)  ! (rates_reaction_id_max)
     994              :          real(dp), pointer, intent(in) :: reaction_neuQs(:)  ! (rates_reaction_id_max)
     995              :          integer, intent(in) :: screening_mode  ! see screen_def
     996              :          real(dp), intent(in) :: stptry  ! try this for 1st step.  0 means try in 1 step.
     997              :          integer, intent(in) :: max_steps  ! maximal number of allowed steps.
     998              :          real(dp), intent(in) :: eps, odescal  ! tolerances.  e.g., set both to 1d-6
     999              :          logical, intent(in) :: use_pivoting  ! for matrix solves
    1000              :          logical, intent(in) :: trace, dbg
    1001              :          interface
    1002              :             include 'burner_finish_substep.inc'
    1003              :          end interface
    1004              :          real(dp), intent(inout) :: ending_x(:) ! (num_isos)
    1005              :          real(dp), intent(inout) :: eps_nuc_categories(:) ! (num_categories)
    1006              :          real(dp), intent(out) :: avg_eps_nuc, eps_neu_total
    1007              :          integer, intent(out) :: nfcn    ! number of function evaluations
    1008              :          integer, intent(out) :: njac    ! number of jacobian evaluations
    1009              :          integer, intent(out) :: nstep   ! number of computed steps
    1010              :          integer, intent(out) :: naccpt  ! number of accepted steps
    1011              :          integer, intent(out) :: nrejct  ! number of rejected steps
    1012              :          integer, intent(out) :: ierr
    1013              : 
    1014              :          call burn_1_zone( &
    1015              :             net_handle, eos_handle, num_isos, num_reactions, t_start, t_end, starting_x, &
    1016              :             num_times_for_interpolation, times, log10Ts_f1, log10Rhos_f1, etas_f1, &
    1017              :             dxdt_source_term, rate_factors, weak_rate_factor, &
    1018              :             reaction_Qs, reaction_neuQs, screening_mode, &
    1019              :             stptry, max_steps, eps, odescal, &
    1020              :             use_pivoting, trace, dbg, burner_finish_substep, &
    1021              :             ending_x, eps_nuc_categories, avg_eps_nuc, eps_neu_total, &
    1022            2 :             nfcn, njac, nstep, naccpt, nrejct, ierr)
    1023              : 
    1024            2 :       end subroutine net_1_zone_burn
    1025              : 
    1026              : 
    1027              :       ! a 1-zone integrator for nets -- for given density
    1028              :       ! evolve lnT according to dlnT/dt = eps_nuc/(Cv*T)
    1029            0 :       subroutine net_1_zone_burn_const_density( &
    1030              :             net_handle, eos_handle, num_isos, num_reactions, t_start, t_end, &
    1031            0 :             starting_x, starting_log10T, log10Rho, &
    1032              :             get_eos_info_for_burn_at_const_density, &
    1033              :             rate_factors, weak_rate_factor, reaction_Qs, reaction_neuQs, &
    1034              :             screening_mode,  &
    1035              :             stptry, max_steps, eps, odescal, &
    1036              :             use_pivoting, trace, dbg, burner_finish_substep, &
    1037              :             ! results
    1038            0 :             ending_x, eps_nuc_categories, ending_log10T, &
    1039              :             avg_eps_nuc, ending_eps_neu_total, &
    1040              :             nfcn, njac, nstep, naccpt, nrejct, ierr)
    1041            2 :          use net_burn_const_density, only: burn_const_density_1_zone
    1042              :          use net_def
    1043              :          use chem_def, only: num_categories
    1044              : 
    1045              :          integer, intent(in) :: net_handle, eos_handle, num_isos, num_reactions
    1046              :          real(dp), intent(in) :: t_start, t_end, starting_x(:)  ! (num_isos)
    1047              :          real(dp), intent(in) :: starting_log10T, log10Rho
    1048              :          interface
    1049              :             include 'burner_const_density_get_eos_info.inc'
    1050              :          end interface
    1051              :          real(dp), intent(in), pointer :: rate_factors(:) ! (num_reactions)
    1052              :          real(dp), intent(in) :: weak_rate_factor
    1053              :          real(dp), pointer, intent(in) :: reaction_Qs(:) ! (rates_reaction_id_max)
    1054              :          real(dp), pointer, intent(in) :: reaction_neuQs(:) ! (rates_reaction_id_max)
    1055              :          integer, intent(in) :: screening_mode ! see screen_def
    1056              :          real(dp), intent(in) :: stptry ! try this for 1st step.  0 means try in 1 step.
    1057              :          integer, intent(in) :: max_steps ! maximal number of allowed steps.
    1058              :          real(dp), intent(in) :: eps, odescal ! tolerances.  e.g., set both to 1d-6
    1059              :          logical, intent(in) :: use_pivoting ! for matrix solves
    1060              :          logical, intent(in) :: trace, dbg
    1061              :          interface
    1062              :             include 'burner_finish_substep.inc'
    1063              :          end interface
    1064              :          real(dp), intent(inout) :: ending_x(:) ! (num_isos)
    1065              :          real(dp), intent(inout) :: eps_nuc_categories(:) ! (num_categories)
    1066              :          real(dp), intent(out) :: ending_log10T, avg_eps_nuc, ending_eps_neu_total
    1067              :          integer, intent(out) :: nfcn    ! number of function evaluations
    1068              :          integer, intent(out) :: njac    ! number of jacobian evaluations
    1069              :          integer, intent(out) :: nstep   ! number of computed steps
    1070              :          integer, intent(out) :: naccpt  ! number of accepted steps
    1071              :          integer, intent(out) :: nrejct  ! number of rejected steps
    1072              :          integer, intent(out) :: ierr
    1073              : 
    1074              :          call burn_const_density_1_zone( &
    1075              :             net_handle, eos_handle, num_isos, num_isos+1, num_reactions, t_start, t_end, &
    1076              :             starting_x, starting_log10T, log10Rho, &
    1077              :             get_eos_info_for_burn_at_const_density, &
    1078              :             rate_factors, weak_rate_factor, reaction_Qs, reaction_neuQs, &
    1079              :             screening_mode,  &
    1080              :             stptry, max_steps, eps, odescal, &
    1081              :             use_pivoting, trace, dbg, burner_finish_substep, &
    1082              :             ending_x, eps_nuc_categories, ending_log10T, avg_eps_nuc, ending_eps_neu_total, &
    1083            0 :             nfcn, njac, nstep, naccpt, nrejct, ierr)
    1084              : 
    1085            0 :       end subroutine net_1_zone_burn_const_density
    1086              : 
    1087              :       ! evolve T according to dT/dt = eps_nuc/Cp while using given P.
    1088              :       !  then find new Rho and Cp to match P and new T.
    1089            2 :       subroutine net_1_zone_burn_const_P( &
    1090              :             net_handle, eos_handle, num_isos, num_reactions,  &
    1091              :             which_solver, starting_temp, starting_x, clip, &
    1092              :             ! for interpolating log10P wrt time &
    1093              :             num_times_for_interpolation, times, log10Ps_f1, &
    1094              :             ! other args for net_get &
    1095              :             rate_factors, weak_rate_factor, &
    1096              :             reaction_Qs, reaction_neuQs, screening_mode,  &
    1097              :             ! args to control the solver &
    1098              :             h, max_step_size, max_steps, rtol, atol, itol, x_min, x_max, which_decsol,  &
    1099              :             ! results &
    1100              :             caller_id, solout, iout,  &
    1101              :             ending_x, ending_temp, ending_rho, ending_lnS, initial_rho, initial_lnS, &
    1102              :             nfcn, njac, nstep, naccpt, nrejct, time_doing_net, time_doing_eos, ierr)
    1103            0 :          use net_burn_const_P, only: burn_1_zone_const_P
    1104              :          use chem_def, only: num_categories
    1105              :          use rates_def, only: num_rvs
    1106              : 
    1107              :          integer, intent(in) :: net_handle, eos_handle
    1108              :          integer, intent(in) :: num_isos
    1109              :          integer, intent(in) :: num_reactions
    1110              :          real(dp), pointer, intent(in) :: starting_x(:)  ! (num_isos)
    1111              :          real(dp), intent(in) :: starting_temp
    1112              :          logical, intent(in) :: clip  ! if true, set negative x's to zero during burn.
    1113              : 
    1114              :          integer, intent(in) :: which_solver  ! as defined in num_def.f
    1115              :          integer, intent(in) :: num_times_for_interpolation  ! ending time is times(num_times); starting time is 0
    1116              :          real(dp), pointer, intent(in) :: times(:)  ! (num_times)
    1117              :          real(dp), pointer, intent(in) :: log10Ps_f1(:)  ! =(4,numtimes) interpolant for log10P(time)
    1118              : 
    1119              :          real(dp), intent(in), pointer :: rate_factors(:)  ! (num_reactions)
    1120              :          real(dp), intent(in) :: weak_rate_factor
    1121              :          real(dp), pointer, intent(in) :: reaction_Qs(:)  ! (rates_reaction_id_max)
    1122              :          real(dp), pointer, intent(in) :: reaction_neuQs(:)  ! (rates_reaction_id_max)
    1123              :          integer, intent(in) :: screening_mode
    1124              : 
    1125              :          ! args to control the solver -- see num/public/num_isolve.dek
    1126              :          real(dp), intent(inout) :: h
    1127              :          real(dp), intent(in) :: max_step_size  ! maximal step size.
    1128              :          integer, intent(in) :: max_steps  ! maximal number of allowed steps.
    1129              :          ! absolute and relative error tolerances
    1130              :          real(dp), pointer :: rtol(:)  ! relative error tolerance (num_isos)
    1131              :          real(dp), pointer :: atol(:)  ! absolute error tolerance (num_isos)
    1132              :          integer, intent(in) :: itol  ! switch for rtol and atol
    1133              :          real(dp), intent(in) :: x_min, x_max  ! bounds on allowed values
    1134              :          integer, intent(in) :: which_decsol  ! from mtx_def
    1135              :          integer, intent(in) :: caller_id
    1136              :          interface  ! subroutine called after each successful step
    1137              :             include "num_solout.dek"
    1138              :          end interface
    1139              :          integer, intent(in)  :: iout
    1140              :          real(dp), intent(inout), pointer :: ending_x(:)
    1141              :          real(dp), intent(out) :: ending_temp, ending_rho, ending_lnS, initial_rho, initial_lnS
    1142              :          integer, intent(out) :: nfcn    ! number of function evaluations
    1143              :          integer, intent(out) :: njac    ! number of jacobian evaluations
    1144              :          integer, intent(out) :: nstep   ! number of computed steps
    1145              :          integer, intent(out) :: naccpt  ! number of accepted steps
    1146              :          integer, intent(out) :: nrejct  ! number of rejected steps
    1147              :          real(dp), intent(inout) :: time_doing_net
    1148              :             ! if < 0, then ignore
    1149              :             ! else on return has input value plus time spent doing eval_net
    1150              :          real(dp), intent(inout) :: time_doing_eos
    1151              :             ! if < 0, then ignore
    1152              :             ! else on return has input value plus time spent doing eos
    1153              :          integer, intent(out) :: ierr
    1154              : 
    1155              :          call burn_1_zone_const_P( &
    1156              :             net_handle, eos_handle, num_isos, num_reactions,  &
    1157              :             which_solver, starting_temp, starting_x, clip, &
    1158              :             num_times_for_interpolation, times, log10Ps_f1, &
    1159              :             rate_factors, weak_rate_factor, &
    1160              :             reaction_Qs, reaction_neuQs, screening_mode,  &
    1161              :             h, max_step_size, max_steps, rtol, atol, itol, x_min, x_max, which_decsol,  &
    1162              :             caller_id, solout, iout, &
    1163              :             ending_x, ending_temp, ending_rho, ending_lnS, initial_rho, initial_lnS, &
    1164            2 :             nfcn, njac, nstep, naccpt, nrejct, time_doing_net, time_doing_eos, ierr)
    1165              : 
    1166            2 :       end subroutine net_1_zone_burn_const_P
    1167              : 
    1168              :       ! approximate beta decay neutrino energies (in MeV)
    1169              :       ! Fowler, Caughlan, Zimmerman, Annual Review Astro. Astrophys., 1975.12:69-112. eqn (1).
    1170            0 :       real(dp) function eval_neutrino_Q(i1, i2)
    1171            2 :          use net_initialize, only:neutrino_Q
    1172              :          integer, intent(in) :: i1, i2  ! i1 decays to i2.  e.g., i1=in13 and i2=ic13
    1173            0 :          eval_neutrino_Q = neutrino_Q(i1, i2)
    1174            0 :       end function eval_neutrino_Q
    1175              : 
    1176              : 
    1177              :       ! for calculating reaction Q
    1178            0 :       real(dp) function isoB(ci)
    1179            0 :          use chem_def, only: del_Mp, del_Mn
    1180              :          integer, intent(in) :: ci
    1181            0 :          isoB = chem_isos% binding_energy(ci) - chem_isos% Z(ci)*del_Mp - chem_isos% N(ci)*del_Mn
    1182            0 :       end function isoB
    1183              : 
    1184              : 
    1185           10 :       subroutine clean_up_fractions(nzlo, nzhi, species, nz, xa, max_sum_abs, xsum_tol, ierr)
    1186              :          ! make sure all fractions are okay and sum to 1.0
    1187            0 :          use net_eval, only: do_clean_up_fractions
    1188              :          integer, intent(in) :: nzlo, nzhi, species, nz
    1189              :          real(dp), intent(inout) :: xa(:,:)  ! (species, nz) ! mass fractions
    1190              :          real(dp), intent(in) :: max_sum_abs
    1191              :          ! if any k has sum(abs(xa(:,k))) greater than this, set ierr = -1 and return.
    1192              :          ! else clip each element abundance to the range 0 to 1 and continue.
    1193              :          real(dp), intent(in) :: xsum_tol
    1194              :          ! if any sum of abundances is now different from 1 by more than this, set ierr = -1
    1195              :          ! otherwise, rescale the abundances so that they sum to 1.
    1196              :          integer, intent(out) :: ierr
    1197           10 :          call do_clean_up_fractions(nzlo, nzhi, species, nz, xa, max_sum_abs, xsum_tol, ierr)
    1198           10 :       end subroutine clean_up_fractions
    1199              : 
    1200              : 
    1201            0 :       subroutine clean1(species, xa, max_sum_abs, xsum_tol, ierr)
    1202           10 :          use net_eval, only: do_clean1
    1203              :          integer, intent(in) :: species
    1204              :          real(dp), intent(inout) :: xa(:)  ! (species)
    1205              :          real(dp), intent(in) :: max_sum_abs, xsum_tol
    1206              :          integer, intent(out) :: ierr
    1207            0 :          call do_clean1(species, xa, 1, max_sum_abs, xsum_tol, ierr)
    1208            0 :       end subroutine clean1
    1209              : 
    1210              :       end module net_lib
        

Generated by: LCOV version 2.0-1