LCOV - code coverage report
Current view: top level - rates/private - screen_chugunov.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.1 % 145 122
Test Date: 2025-05-08 18:23:42 Functions: 100.0 % 1 1

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2018  Sam Jones, Robert Farmer & 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              : ! Implement screening a la Chugunov, DeWitt & Yakovlev 2007, PhRvD, 76, 025028
      21              : 
      22              :    module screening_chugunov
      23              :       use math_lib
      24              :       use const_def, only: dp, amu, hbar, kerg, four_thirds, pi, pi2, pi4, qe, rbohr
      25              :       use rates_def, only: screen_info
      26              :       use math_def
      27              : 
      28              :       implicit none
      29              :       private
      30              : 
      31              :       ! there are various realms of applicability in the Chugunov paper, for
      32              :       ! the particle-in-cell Monte-Carlo calculations, for the MKB
      33              :       ! approximation, and for the Potekhin-Cabrier-based fit to the MKB
      34              :       ! results for the mean field potential H(r).
      35              :       ! hence, here are parameters for smoothly limiting the domain of application
      36              :       real(dp), parameter ::   gamfitlim = 600.0d0  !< upper limit for applicability of fit for h(gamma)
      37              :       real(dp), parameter ::   g0 = 590.0d0        !< lower limit to start blending from
      38              :       real(dp), parameter ::   deltagam = gamfitlim - g0  ! How much to blend over the gamma boundaries
      39              :       real(dp), parameter ::   tp2 = 0.2d0         !< minimum allowed ratio T/T_p before fading out
      40              :       real(dp), parameter ::   tp1 = 0.1d0         !< floor value of T/T_p (T_p = plasma temperature)
      41              :       real(dp), parameter ::   deltatp = tp2 - tp1         !< Blend over the tp boundary
      42              : 
      43              :       ! coefficients from chugunov
      44              :       real(dp), parameter ::   c_a1 = 2.7822d0
      45              :       real(dp), parameter ::   c_a2 = 98.34d0
      46              :       real(dp), parameter ::   c_a3 = sqrt(3.0d0) - c_a1/sqrt(c_a2)
      47              :       real(dp), parameter ::   c_b1 = -1.7476d0
      48              :       real(dp), parameter ::   c_b2 = 66.07d0
      49              :       real(dp), parameter ::   c_b3 = 1.12d0
      50              :       real(dp), parameter ::   c_b4 = 65.d0
      51              :       real(dp), parameter ::   alfa = 0.022d0
      52              : 
      53              :       real(dp), parameter :: x13   = 1.0d0/3.0d0
      54              :       real(dp), parameter :: x12   = 1.0d0/2.0d0
      55              :       real(dp), parameter :: x23   = 2.0d0/3.0d0
      56              :       real(dp), parameter :: x32   = 3.0d0/2.0d0
      57              :       real(dp), parameter :: x43   = 4.0d0/3.0d0
      58              :       real(dp), parameter :: x53   = 5.0d0/3.0d0
      59              : 
      60              :       real(dp), parameter :: h0fitlim = 300d0, h0fit0 = 295d0
      61              :       real(dp), parameter :: deltah0fit = h0fitlim - h0fit0
      62              : 
      63              :       public  eval_screen_chugunov
      64              : 
      65              :    contains
      66              : 
      67              : 
      68      2079846 :       subroutine eval_screen_chugunov(sc, z1, z2, a1, a2, screen, dscreendt, dscreendd, ierr)
      69              : 
      70              :          type (Screen_Info)  :: sc
      71              :          real(dp),intent(in) ::    z1, z2      !< charge numbers of reactants
      72              :          real(dp),intent(in) ::    a1, a2     !< mass numbers of reactants
      73              :          real(dp),intent(out) ::   screen     !< on return, screening factor for this reaction
      74              :          real(dp),intent(out) ::   dscreendt     !< on return, temperature derivative of the screening factor
      75              :          real(dp),intent(out) ::   dscreendd    !< on return, density derivative of the screening factor
      76              :          integer, intent(out) ::   ierr
      77              : 
      78      2079846 :          real(dp) ::   z1z2       !< z1*z2
      79      2079846 :          real(dp) ::   t1, dt1dt, dt1dd
      80      2079846 :          real(dp) ::   t2, dt2dt, dt2dd
      81      2079846 :          real(dp) ::   t3, dt3dt, dt3dd  !< the three terms in the fitting formula for h0fit
      82      2079846 :          real(dp) ::   h0fit, dh0fitdt, dh0fitdd  !< mean field fit
      83      2079846 :          real(dp) ::   denom, ddenomdt, ddenomdd, denom2
      84      2079846 :          real(dp) ::   tp, dtpdd, wp, dwpdd     !< plasma temperature and frequency
      85      2079846 :          real(dp) ::   tn, dtndd, dtndt         !< normalised temperature (tk/tp)
      86      2079846 :          real(dp) ::   beta, dbetadt, dbetadd, gama, dgamadt, dgamadd  !< coeffs of zeta formula
      87      2079846 :          real(dp) ::   gam, dgamdt, dgamdd
      88      2079846 :          real(dp) ::   gamtild, dgamtilddt, dgamtilddd    !< "effective" coulomb coupling parameter
      89      2079846 :          real(dp) ::   gamtild2   !< "effective" coulomb coupling parameter squared
      90      2079846 :          real(dp) ::   zeta, dzetadt, dzetadd       !< function of plasma temperature
      91      2079846 :          real(dp) ::   zeta2, zeta3
      92      2079846 :          real(dp) ::   a_1, da_1dd, a_2,da_2dd   !< ion sphere radii
      93      2079846 :          real(dp) ::   a_av, da_avdd       !< average ion sphere radii
      94      2079846 :          real(dp) ::   a_e        !< electron sphere radius
      95      2079846 :          real(dp) ::   a_b        !< bohr radius
      96      2079846 :          real(dp) ::   rs         !< ion sphere radius normalised to bohr radius
      97              :          !real(dp) ::   m1, m2     !< ion masses
      98              :          !real(dp) ::   n1, n2     !< number density of ions of types 1 and 2
      99      2079846 :          real(dp) ::   ntot, dntotdd       !< total number density of these ions
     100              :          !real(dp) ::   s          !< evaluated sigmoid function
     101      2079846 :          real(dp) ::   mav           !< average ion mass
     102      2079846 :          real(dp) ::   A, B, C, U, dAdt, dAdd, dBdt, dBdd, dCdt, dCdd
     103      2079846 :          real(dp) ::   temp, rho, abar, zbar, rr
     104      2079846 :          real(dp) ::   alpha, dalphadgam, dbetadgam, dalphadtn,dbetadtn
     105      2079846 :          real(dp) ::   tk, dtkdt, dtkdd
     106              : 
     107              :          ! check whether both reactants are charged ions
     108              : 
     109      2079846 :          screen = 1d0
     110      2079846 :          dscreendt = 0d0
     111      2079846 :          dscreendd = 0d0
     112      2079846 :          ierr = 0
     113              : 
     114              :          ! Must be charged ions
     115      2079846 :          if (z1 <= 0d0 .or. z2  <= 0d0) then
     116            0 :             return
     117              :          end if
     118              : 
     119              :          ! No free charges to screen things
     120      2079846 :          if(sc% zbar<=1d0) return
     121              : 
     122              : 
     123      2079846 :          rho = sc% den
     124      2079846 :          temp = sc% temp
     125      2079846 :          zbar = sc% zbar
     126      2079846 :          abar = sc% abar
     127      2079846 :          rr = sc% rr  ! den/abar
     128              : 
     129              :          ! ion masses and number densities
     130      2079846 :          mav   = abar * amu
     131              :          ! ntot  = den / (amu*abar)
     132      2079846 :          ntot  = sc% ntot
     133      2079846 :          dntotdd = 1d0/(amu*abar)
     134              : 
     135              :          ! ion and electron sphere radii (itoh 1979 eq 1-3)
     136              :          !a_e = pow((3.d0 /(pi4 * zbar * ntot)),x13)
     137      2079846 :          a_e = sc% a_e
     138              : 
     139      2079846 :          a_1 = a_e * pre_z(int(z1))%z1_3  !pow(z1,x13)
     140      2079846 :          a_2 = a_e * pre_z(int(z2))%z1_3  !pow(z2,x13)
     141              : 
     142      2079846 :          da_1dd = -x13 * a_1/rho
     143      2079846 :          da_2dd = -x13 * a_2/rho
     144              : 
     145      2079846 :          a_av  = 0.5d0 * (a_1 + a_2)
     146      2079846 :          da_avdd = 0.5d0 * (da_1dd + da_2dd)
     147              : 
     148      2079846 :          z1z2 = z1 * z2
     149              : 
     150              :          ! bohr radius and normalised ion sphere radius
     151              : 
     152      2079846 :          a_b = rbohr/z1z2/ntot
     153      2079846 :          rs  = a_av / a_b
     154              : 
     155              :          ! plasma frequency and temperature (chugunov 2007 eq 2)
     156              : 
     157      2079846 :          wp = sqrt((pi4 * z1z2 * qe * qe * ntot/mav))
     158      2079846 :          dwpdd = x12 * wp/rho
     159              : 
     160      2079846 :          tp = hbar*wp/kerg
     161      2079846 :          dtpdd = (hbar/kerg) * dwpdd
     162              : 
     163      2079846 :          tn = temp/tp
     164      2079846 :          dtndt = 1d0/tp
     165      2079846 :          dtndd = -tn/tp * dtpdd
     166              : 
     167              :          ! Revise temperature used if nearing low tp values
     168      2079846 :          tk = temp
     169      2079846 :          dtkdt = 1d0
     170      2079846 :          dtkdd = 0d0
     171      2079846 :          denom = tp * (tk * dtpdd - tp * dtkdd)/(tk * tk * tk)
     172              : 
     173              :          ! Blend out for low Tp values
     174      2079846 :          if ( tn <= tp1)then
     175            0 :             tk = tp1 * tp
     176            0 :             dtkdt = 0d0
     177            0 :             dtkdd = tp1 * dtpdd
     178            0 :             denom = 0d0  ! Set as zero otherwise floating point issues cause small error in the subtraction (tk * dtpdd - tp * dtkdd)
     179              : 
     180      2079846 :          else if (tn >tp1 .and. tn <= tp2) then
     181              : 
     182            0 :             alpha = 0.5d0 * (1d0 - cospi((tn-tp1)/deltatp))
     183            0 :             dalphadtn = 0.5d0 * (pi/deltatp) * sinpi((tn-tp1)/deltatp)
     184              : 
     185            0 :             beta = 1.d0 - alpha
     186            0 :             dbetadtn = -dalphadtn
     187              : 
     188            0 :             dtkdt = (dbetadtn * dtndt * tp1 * tp) + (dalphadtn * dtndt * tp2 * tp)
     189              :             dtkdd = (beta * tp1 * dtpdd) + (dbetadtn * dtndd * tp1 * tp) + &
     190            0 :                      (alpha * tp2 * dtpdd) + (dalphadtn * dtndd * tp2 * tp)
     191              : 
     192            0 :             tk = beta * (tp1 * tp) + alpha * (tp2 * tp)
     193            0 :             denom = tp * (tk * dtpdd - tp * dtkdd)/(tk * tk * tk)
     194              :          end if
     195              : 
     196              :          ! zeta (chugunov 2007 eq 3)
     197      2079846 :          U = four_thirds*(tp * tp)/(pi2 * tk * tk)
     198      2079846 :          zeta = pow(U,x13)
     199      2079846 :          dzetadt = -x23 * (zeta/tk) * dtkdt
     200      2079846 :          dzetadd =  x13 * (zeta/U) * (four_thirds/pi2) * 2.d0 * denom
     201              : 
     202              :          ! coulomb coupling parameter gamma (itoh 1979 eq 4)
     203      2079846 :          gam = z1z2 * qe * qe/(a_av * tk * kerg)
     204      2079846 :          dgamdt = -(gam / tk) * dtkdt
     205      2079846 :          dgamdd = -(gam/(a_av * tk)) * (tk * da_avdd + a_av * dtkdd)
     206              : 
     207      2079846 :          if (gam >=gamfitlim) then
     208              : 
     209              :             gam = gamfitlim
     210              :             dgamdt = 0d0
     211              :             dgamdd = 0d0
     212              : 
     213      2079846 :          else if (gam <= gamfitlim .and. gam >= g0 ) then
     214            0 :             alpha = 0.5d0 * (1d0 - cospi((gam-g0)/deltagam))
     215            0 :             dalphadgam = 0.5d0 * pi * sinpi((gam-g0)/deltagam) * (1d0/deltagam)
     216            0 :             beta = 1.d0 - alpha
     217            0 :             dbetadgam = -dalphadgam
     218              : 
     219            0 :             dgamdt = beta * dgamdt + (dbetadgam * dgamdt) * gam + (dalphadgam * dgamdt) * gamfitlim
     220            0 :             dgamdd = beta * dgamdd + (dbetadgam * dgamdd) * gam + (dalphadgam * dgamdd) * gamfitlim
     221              : 
     222            0 :             gam = beta * gam + alpha * gamfitlim
     223              : 
     224              :          end if
     225              : 
     226              :          ! coefficients of zeta dependent on the ion coulomb coupling
     227              :          ! parameter (gam) (chugunov 2007, just after eq 21)
     228              : 
     229      2079846 :          beta = 0.41d0 - 0.6d0/gam
     230      2079846 :          dbetadt = 0.6d0/(gam * gam) * dgamdt
     231      2079846 :          dbetadd = 0.6d0/(gam * gam) * dgamdd
     232              : 
     233      2079846 :          gama = 0.06d0 + 2.2d0/gam
     234      2079846 :          dgamadt = -2.2d0/(gam * gam) * dgamdt
     235      2079846 :          dgamadd = -2.2d0/(gam * gam) * dgamdd
     236              : 
     237              :          ! gamma tilda (chugunov 2007 eq 21)
     238      2079846 :          zeta2 = zeta * zeta
     239      2079846 :          zeta3 = zeta2 * zeta
     240              : 
     241      2079846 :          U = (1d0 + alfa * zeta + beta * zeta2 + gama * zeta3)
     242      2079846 :          denom = pow(U,-x13)
     243      2079846 :          denom2 = denom/U  ! pow(U,-x43)
     244              :          ddenomdt = -x13 * denom2 * &
     245              :                      ((alfa * dzetadt)  + (zeta2 * dbetadt + 2d0 * dzetadt * beta * zeta) + &
     246      2079846 :                      (zeta3 * dgamadt + 3d0 * dzetadt * gama * zeta2 ))
     247              :          ddenomdd = -x13 * denom2 * &
     248              :                      ((alfa * dzetadd)  + (zeta2 * dbetadd + 2d0 * dzetadd * beta * zeta) + &
     249      2079846 :                      (zeta3 * dgamadd + 3d0 * dzetadd * gama * zeta2 ))
     250              : 
     251      2079846 :          gamtild  = gam * denom
     252      2079846 :          dgamtilddt =  ddenomdt * gam + dgamdt * denom
     253      2079846 :          dgamtilddd =  ddenomdd * gam + dgamdd * denom
     254              : 
     255      2079846 :          gamtild2 = gamtild * gamtild
     256              :          ! for for mean field potential H (chugunov 2007 eq 19)
     257              : 
     258      2079846 :          A = gamtild * sqrt(gamtild)
     259      2079846 :          dAdt = x32 * (A/gamtild) * dgamtilddt
     260      2079846 :          dAdd = x32 * (A/gamtild) * dgamtilddd
     261              : 
     262      2079846 :          B = c_a1/sqrt(c_a2 + gamtild)
     263      2079846 :          dBdt = -1d0/2d0 * B/(c_a2 + gamtild) * dgamtilddt
     264      2079846 :          dBdd = -1d0/2d0 * B/(c_a2 + gamtild) * dgamtilddd
     265              : 
     266      2079846 :          C = c_a3/(1d0 + gamtild)
     267      2079846 :          dCdt = -C/(1d0 + gamtild) * dgamtilddt
     268      2079846 :          dCdd = -C/(1d0 + gamtild) * dgamtilddd
     269              : 
     270      2079846 :          t1 = A * ( B + C )
     271      2079846 :          dt1dt = A * ( dBdt + dCdt ) + dAdt * ( B + C )
     272      2079846 :          dt1dd = A * ( dBdd + dCdd ) + dAdd * ( B + C )
     273              : 
     274      2079846 :          denom = c_b2 + gamtild
     275      2079846 :          ddenomdt = dgamtilddt
     276      2079846 :          ddenomdd = dgamtilddd
     277      2079846 :          t2 = c_b1 * gamtild2 / denom
     278      2079846 :          dt2dt = (( denom * c_b1 * 2d0 * gamtild * dgamtilddt ) - (c_b1 * gamtild2 * ddenomdt)) / (denom * denom)
     279      2079846 :          dt2dd = (( denom * c_b1 * 2d0 * gamtild * dgamtilddd ) - (c_b1 * gamtild2 * ddenomdd))/ (denom * denom)
     280              : 
     281      2079846 :          denom  = c_b4 + gamtild2
     282      2079846 :          ddenomdt = 2d0 * gamtild * dgamtilddt
     283      2079846 :          ddenomdd = 2d0 * gamtild * dgamtilddd
     284      2079846 :          t3 = c_b3 * gamtild2 / denom
     285      2079846 :          dt3dt = (( denom * c_b3 * 2d0 * gamtild * dgamtilddt ) - (c_b3 * gamtild2 * ddenomdt)) / (denom * denom)
     286      2079846 :          dt3dd = (( denom * c_b3 * 2d0 * gamtild * dgamtilddd ) - (c_b3 * gamtild2 * ddenomdd)) / (denom * denom)
     287              : 
     288      2079846 :          h0fit = t1 + t2 + t3
     289      2079846 :          dh0fitdt = dt1dt + dt2dt + dt3dt
     290      2079846 :          dh0fitdd = dt1dd + dt2dd + dt3dd
     291              : 
     292      2079846 :          dscreendt = dh0fitdt * screen
     293      2079846 :          dscreendd = dh0fitdd * screen
     294              : 
     295              :          ! limit screening factor to h0fitlim
     296      2079846 :          if (h0fit > h0fitlim) then
     297            0 :             h0fit = h0fitlim
     298            0 :             dh0fitdt = 0d0
     299            0 :             dh0fitdd = 0d0
     300              :          end if
     301              : 
     302      2079846 :          screen = exp(h0fit)
     303      2079846 :          dscreendt = dh0fitdt * screen
     304      2079846 :          dscreendd = dh0fitdd * screen
     305              : 
     306              :       end subroutine eval_screen_chugunov
     307              : 
     308              :    end module screening_chugunov
     309              : 
        

Generated by: LCOV version 2.0-1