LCOV - code coverage report
Current view: top level - rates/private - reaclib_eval.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.2 % 116 107
Test Date: 2025-05-08 18:23:42 Functions: 100.0 % 6 6

            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 reaclib_eval
      21              :       use rates_def
      22              :       use math_lib
      23              : 
      24              :       implicit none
      25              : 
      26              :       real(dp), parameter :: &
      27              :          lam_max = 1d99, &
      28              :          ln1_max = 227.955924206411d0  ! log(lam_max)
      29              : 
      30              : 
      31              :       contains
      32              : 
      33              : 
      34       852157 :       subroutine reaction_rates( &
      35              :             num_lambdas, lo, hi, T9, rates, nuclides, forward_only, &
      36              :             lambda, dlambda_dlnT, &
      37              :             rlambda, drlambda_dlnT, &
      38              :             ierr)
      39              :          integer, intent(in) :: num_lambdas, lo, hi
      40              :          real(dp), intent(in) :: T9
      41              :          type(reaction_data), intent(in) :: rates
      42              :          type(nuclide_data), intent(in) :: nuclides
      43              :          logical, intent(in) :: forward_only
      44              :          real(dp), intent(out) :: lambda, dlambda_dlnT
      45              :          real(dp), intent(out) :: rlambda, drlambda_dlnT
      46              :          integer, intent(out) :: ierr
      47              : 
      48              :          real(dp), dimension(num_lambdas), target :: &
      49      8054502 :             ln_lambdas_ar, lambdas_ar, dlambdas_dlnT_ar, &
      50      8054502 :             ln_rlambdas_ar, rlambdas_ar, drlambdas_dlnT_ar
      51              :          real(dp), dimension(:), pointer :: &
      52              :             ln_lambdas, lambdas, dlambdas_dlnT, &
      53       852157 :             ln_rlambdas, rlambdas, drlambdas_dlnT
      54              : 
      55              :          include 'formats'
      56              : 
      57       852157 :          ierr = 0
      58              : 
      59       852157 :          ln_lambdas => ln_lambdas_ar
      60       852157 :          lambdas => lambdas_ar
      61       852157 :          dlambdas_dlnT => dlambdas_dlnT_ar
      62       852157 :          ln_rlambdas => ln_rlambdas_ar
      63       852157 :          rlambdas => rlambdas_ar
      64       852157 :          drlambdas_dlnT => drlambdas_dlnT_ar
      65              : 
      66              :          call compute_some_lambdas( &
      67       852157 :             num_lambdas, lo, hi, T9, rates, ln_lambdas, lambdas, dlambdas_dlnT)
      68      2684834 :          lambda = sum(lambdas(1:num_lambdas))
      69      2684834 :          dlambda_dlnT = sum(dlambdas_dlnT(1:num_lambdas))
      70              : 
      71       852157 :          if (forward_only) then
      72            0 :             rlambda = 0
      73            0 :             drlambda_dlnT = 0
      74              :          else
      75              :             call compute_some_inverse_lambdas( &
      76              :                num_lambdas, lo, hi, T9, rates, &
      77              :                ln_lambdas, lambdas, dlambdas_dlnT, &
      78       852157 :                rlambdas, drlambdas_dlnT)
      79      2684834 :             rlambda = sum(rlambdas(1:num_lambdas))
      80      2684834 :             drlambda_dlnT = sum(drlambdas_dlnT(1:num_lambdas))
      81              :          end if
      82              : 
      83       852157 :       end subroutine reaction_rates
      84              : 
      85              : 
      86       852157 :       subroutine compute_some_lambdas( &
      87       852157 :             num_lambdas, lo, hi, T9, rates, ln_lambda, lambda, dlambda_dlnT)
      88              :          use utils_lib, only: is_bad
      89              :          use const_def, only: dp, one_third, two_thirds, four_thirds, five_thirds
      90              :          integer, intent(in) :: num_lambdas, lo, hi  ! range of rates to do
      91              :          real(dp), intent(in) :: T9
      92              :          type(reaction_data), intent(in) :: rates
      93              :          real(dp), dimension(:), intent(out) :: ln_lambda, lambda, dlambda_dlnT
      94              : 
      95      6817256 :          real(dp) :: T9inv, ln1
      96     18747454 :          real(dp), dimension(7) :: T9fac, dT9fac_dT9, dT9fac_dlnT
      97              :          integer :: i, j
      98              : 
      99              :          include 'formats'
     100              : 
     101       852157 :          T9inv = 1d0/T9
     102              : 
     103       852157 :          T9fac(1) = 1d0
     104       852157 :          dT9fac_dT9(1) = 0d0
     105              : 
     106       852157 :          T9fac(2) = T9inv
     107       852157 :          dT9fac_dT9(2) = -T9inv*T9inv
     108              : 
     109       852157 :          T9fac(3) = pow(T9inv,one_third)
     110       852157 :          dT9fac_dT9(3) = -one_third*pow(T9inv,four_thirds)
     111              : 
     112       852157 :          T9fac(4) = pow(T9,one_third)
     113       852157 :          dT9fac_dT9(4) = one_third*pow(T9inv,two_thirds)
     114              : 
     115       852157 :          T9fac(5) = T9
     116       852157 :          dT9fac_dT9(5) = 1d0
     117              : 
     118       852157 :          T9fac(6) = pow(T9,five_thirds)
     119       852157 :          dT9fac_dT9(6) = five_thirds*pow(T9,two_thirds)
     120              : 
     121       852157 :          T9fac(7) = log(T9)
     122       852157 :          dT9fac_dT9(7) = T9inv
     123              : 
     124      6817256 :          dT9fac_dlnT = T9*dT9fac_dT9
     125              : 
     126      2684834 :          do i = lo, hi
     127      1832677 :             j = i+1-lo
     128     14661416 :             ln1 = dot_product(T9fac(:), rates% coefficients(:,i))
     129      2684834 :             if (ln1 > ln1_max) then
     130            0 :                ln_lambda(j) = ln1_max
     131            0 :                lambda(j) = lam_max  ! == exp(ln1_max)
     132            0 :                dlambda_dlnT(j) = 0
     133              :             else
     134      1832677 :                ln_lambda(j) = ln1
     135      1832677 :                lambda(j) = exp(ln_lambda(j))
     136              :                dlambda_dlnT(j) = &
     137     14661416 :                   dot_product(dT9fac_dlnT(:), rates% coefficients(:,i))*lambda(j)
     138              :             end if
     139              :          end do
     140              : 
     141       852157 :       end subroutine compute_some_lambdas
     142              : 
     143              : 
     144       852157 :       subroutine compute_some_inverse_lambdas( &
     145              :             num_lambdas, lo, hi, T9, rates, &
     146       852157 :             ln_lambda, lambda, dlambda_dlnT, &
     147       852157 :             inv_lambda, dinv_lambda_dlnT)
     148              :          use utils_lib, only: is_bad
     149              :          use chem_def, only: Tpart, npart
     150              :          use chem_lib, only: get_partition_fcn_indx
     151              :          integer, intent(in) :: num_lambdas, lo, hi  ! range of rates to do
     152              :          real(dp), intent(in) :: T9
     153              :          type(reaction_data), intent(in) :: rates
     154              :          real(dp), dimension(:), intent(in) :: ln_lambda, lambda, dlambda_dlnT
     155              :          real(dp), dimension(:), intent(out) :: inv_lambda, dinv_lambda_dlnT
     156              : 
     157              :          integer :: indx,indxp
     158              :          integer :: i, j
     159      7202345 :          real(dp), dimension(num_lambdas) :: A, Qratio, dQratio_dlnT
     160      4389148 :          real(dp) :: tfac, dtfac_dlnT, lnT9, T9i, dT9i_dlnT, ln1, fac1, dfac1_dlnT, dln1_dlnT,blurp
     161              : 
     162              :          include 'formats'
     163              : 
     164              :          ! find index of partition function and logarithmically interpolate
     165       852157 :          indx = get_partition_fcn_indx(T9)
     166       852157 :          if (indx >= npart) indx = npart-1
     167       852157 :          if (indx < 1) then
     168       846240 :             Qratio(1:num_lambdas) = 1d0
     169       846240 :             dQratio_dlnT(1:num_lambdas) = 0d0
     170              :          else
     171       577505 :             indxp = indx+1
     172       577505 :             tfac = (T9-Tpart(indx))/(Tpart(indxp)-Tpart(indx))
     173       577505 :             dtfac_dlnT = T9/(Tpart(indxp)-Tpart(indx))
     174      1838594 :             do i = lo, hi
     175      1261089 :                j = i+1-lo
     176      1261089 :                A(j) = rates% inverse_part(indxp,i)/rates% inverse_part(indx,i)
     177      1261089 :                blurp = pow(A(j),tfac)
     178      1261089 :                Qratio(j) = rates% inverse_part(indx,i) * blurp
     179      1838594 :                dQratio_dlnT(j) = Qratio(j)*log(A(j))*dtfac_dlnT
     180              :             end do
     181              :          end if
     182              : 
     183       852157 :          lnT9 = log(T9)
     184       852157 :          T9i = 1d0/T9
     185       852157 :          dT9i_dlnT = -T9i
     186              : 
     187      2684834 :          do i = lo, hi
     188              : 
     189      1832677 :             j = i+1-lo
     190              : 
     191              :             ln1 = ln_lambda(j) + &
     192              :                   rates% inverse_coefficients(1,i) + &
     193              :                   rates% inverse_coefficients(2,i)*T9i + &
     194      1832677 :                   1.5d0*rates% inverse_exp(i)*lnT9
     195              : 
     196      1832677 :             if (ln1 < ln1_max) then
     197      1832677 :                fac1 = exp(ln1)
     198              : 
     199              :                dln1_dlnT = dlambda_dlnT(j)/max(1d-99,lambda(j)) + &
     200              :                      rates% inverse_coefficients(2,i)*dT9i_dlnT + &
     201      1832677 :                      1.5d0*rates% inverse_exp(i)
     202              : 
     203      1832677 :                dfac1_dlnT = dln1_dlnT*fac1
     204              : 
     205              :             else
     206            0 :                ln1 = ln1_max
     207            0 :                fac1 = lam_max  ! == exp(ln1_max)
     208            0 :                dln1_dlnT = 0
     209            0 :                dfac1_dlnT = 0
     210              :             end if
     211              : 
     212      1832677 :             inv_lambda(j) = fac1*Qratio(j)
     213      1832677 :             if (lambda(j) < 1d-99) then
     214       145358 :                dinv_lambda_dlnT(j) = 0
     215       145358 :                cycle
     216              :             end if
     217              : 
     218      2539476 :             dinv_lambda_dlnT(j) = dfac1_dlnT*Qratio(j) + fac1*dQratio_dlnT(j)
     219              : 
     220              :          end do
     221              : 
     222       852157 :       end subroutine compute_some_inverse_lambdas
     223              : 
     224              : 
     225       232616 :       integer function do_reaclib_lookup(handle, rates_dict) result(indx)
     226              :          ! returns first reaction index that matches handle.
     227              :          ! there may be several following that one having the same handle.
     228              :          ! returns 0 if handle doesn't match any of the reactions
     229       852157 :          use utils_lib, only: integer_dict_lookup
     230              :          character(len=*), intent(in) :: handle  ! as in rates% reaction_handle
     231              :          type (integer_dict), pointer :: rates_dict  ! from create_reaclib_rates_dict
     232              :          integer :: ierr
     233              :          ierr = 0
     234       232616 :          call integer_dict_lookup(rates_dict, handle, indx, ierr)
     235       232616 :          if (ierr /= 0) indx = 0
     236       232616 :       end function do_reaclib_lookup
     237              : 
     238              : 
     239       232596 :       subroutine do_reaclib_indices_for_reaction(handle, rates, lo, hi, ierr)
     240              :          character(len=*), intent(in) :: handle  ! as in rates% reaction_handle
     241              :          type(reaction_data), intent(in) :: rates
     242              :          integer, intent(out) :: lo, hi
     243              :          integer, intent(out) :: ierr
     244              :          integer :: ir
     245              :          include 'formats'
     246       232596 :          ierr = 0
     247       232596 :          lo = 0
     248       232596 :          hi = 0
     249       232596 :          lo = do_reaclib_lookup(handle, rates% reaction_dict)
     250       232596 :          if (lo == 0) then
     251          339 :             ierr = -1
     252          339 :             return
     253              :          end if
     254       232257 :          hi = rates% nreactions
     255       232257 :          do ir = lo+1, rates% nreactions
     256       232257 :             if (rates% reaction_handle(ir) /= handle) then
     257       232257 :                hi = ir-1
     258       232257 :                exit
     259              :             end if
     260              :          end do
     261       634517 :          do ir = lo-1, 1, -1
     262       634517 :             if (rates% reaction_handle(ir) /= handle) then
     263       232257 :                lo = ir+1
     264       232257 :                exit
     265              :             end if
     266              :          end do
     267              :       end subroutine do_reaclib_indices_for_reaction
     268              : 
     269              : 
     270       852157 :       subroutine do_reaclib_reaction_rates( &
     271              :             lo, hi, T9, rates, nuclides, forward_only, &
     272              :             lambda, dlambda_dlnT, &
     273              :             rlambda, drlambda_dlnT, &
     274              :             ierr)
     275              :          integer, intent(in) :: lo, hi  ! from reaclib_indices_for_reaction
     276              :          real(dp), intent(in) :: T9
     277              :          type(reaction_data), intent(in) :: rates
     278              :          type(nuclide_data), intent(in) :: nuclides
     279              :          logical, intent(in) :: forward_only
     280              :          real(dp), intent(out) :: lambda, dlambda_dlnT
     281              :          real(dp), intent(out) :: rlambda, drlambda_dlnT
     282              :          integer, intent(out) :: ierr
     283              :          call reaction_rates( &
     284              :             hi-lo+1, lo, hi, T9, rates, nuclides, forward_only, &
     285              :             lambda, dlambda_dlnT, &
     286              :             rlambda, drlambda_dlnT, &
     287       852157 :             ierr)
     288       852157 :       end subroutine do_reaclib_reaction_rates
     289              : 
     290              : 
     291              : 
     292              :       end module reaclib_eval
        

Generated by: LCOV version 2.0-1