LCOV - code coverage report
Current view: top level - eos/private - eospc_eval.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 193 0
Test Date: 2025-05-08 18:23:42 Functions: 0.0 % 4 0

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2017-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 eospc_eval
      21              :       use eos_def
      22              :       use auto_diff
      23              :       use const_def, only: dp, qe, qp, avo, crad, ln10, arg_not_provided, amu, kerg, one_third, four_thirds_pi
      24              :       use utils_lib, only: is_bad, mesa_error
      25              :       use math_lib
      26              : 
      27              :       implicit none
      28              : 
      29              :       contains
      30              : 
      31            0 :       subroutine Get_PC_alfa( &
      32              :             rq, logRho, logT, Z, abar, zbar, &
      33              :             alfa, d_alfa_dlogT, d_alfa_dlogRho, &
      34              :             ierr)
      35              :          use const_def, only: dp
      36              :          type (EoS_General_Info), pointer :: rq
      37              :          real(dp), intent(in) :: logRho, logT, Z, abar, zbar
      38              :          real(dp), intent(out) :: alfa, d_alfa_dlogT, d_alfa_dlogRho
      39              :          integer, intent(out) :: ierr
      40            0 :          real(dp) :: logGe0, logGe, logGe_lo, logGe_hi, &
      41            0 :             A, B, dA_dlnT, dA_dlnRho, dB_dlnT, dB_dlnRho, dlogGe_dlogT, dlogGe_dlogRho, &
      42            0 :             logT_lo, logT_hi, logRho_lo, logRho_hi
      43              : 
      44              :          include 'formats'
      45              : 
      46            0 :          ierr = 0
      47              : 
      48            0 :          d_alfa_dlogT = 0d0
      49            0 :          d_alfa_dlogRho = 0d0
      50              : 
      51            0 :          logRho_lo = rq% logRho2_PC_limit  ! don't use PC for logRho < this
      52            0 :          logRho_hi = rq% logRho1_PC_limit  ! okay for pure PC for logRho > this
      53              : 
      54            0 :          if (rq% PC_use_Gamma_limit_instead_of_T) then
      55              :             !gamma_e = (qe**2)*(four_thirds_pi*avo*Rho*zbar/abar)**one_third/(kerg*T)
      56              :             !logGe = logGe0 + logRho/3 - logT
      57              :             ! where Ge0 = (qe**2)*(four_thirds_pi*avo*zbar/abar)**one_third/kerg
      58              :             logGe0 = log10( &
      59            0 :                  qe*qe*pow(four_thirds_pi*avo*zbar/abar, one_third)/kerg)
      60            0 :             logGe = logGe0 + logRho/3 - logT
      61            0 :             logGe_lo = rq% log_Gamma_e_all_HELM  ! HELM for logGe <= this
      62            0 :             logGe_hi = rq% log_Gamma_e_all_PC  ! PC for logGe >= this
      63            0 :             logT_lo = logGe0 + logRho_lo/3 - logGe_lo
      64            0 :             logT_hi = logGe0 + logRho_hi/3 - logGe_hi
      65            0 :             if (logRho <= logRho_lo .or. logGe <= logGe_lo) then
      66            0 :                alfa = 1d0  ! no PC
      67            0 :             else if (logRho >= logRho_hi .and. logGe >= logGe_hi) then
      68            0 :                alfa = 0d0  ! pure PC
      69            0 :             else if (logT >= logT_hi) then  ! blend in logGe
      70            0 :                alfa = (logGe_hi - logGe)/(logGe_hi - logGe_lo)
      71            0 :                dlogGe_dlogT = -1d0
      72            0 :                dlogGe_dlogRho = 1d0/3d0
      73            0 :                d_alfa_dlogT = -dlogGe_dlogT/(logGe_hi - logGe_lo)
      74            0 :                d_alfa_dlogRho = -dlogGe_dlogRho/(logGe_hi - logGe_lo)
      75              :             else  ! blend in logRho
      76            0 :                if (logT >= logT_lo) logRho_lo = (logT_lo + logGe_lo - logGe0)*3
      77            0 :                alfa = (logRho_hi - logRho)/(logRho_hi - logRho_lo)
      78            0 :                d_alfa_dlogRho = -1d0/(logRho_hi - logRho_lo)
      79              :             end if
      80              :          else
      81            0 :             logT_lo = rq% logT1_PC_limit  ! okay for pure PC for logT < this (like logT_all_OPAL)
      82            0 :             logT_hi = rq% logT2_PC_limit  ! don't use PC for logT > this (like logT_all_HELM)
      83            0 :             if (logRho <= logRho_lo .or. logT >= logT_hi) then
      84            0 :                alfa = 1d0  ! no PC
      85            0 :             else if (logRho >= logRho_hi .and. logT <= logT_lo) then
      86            0 :                alfa = 0d0  ! pure PC
      87            0 :             else if (logT >= logT_lo) then  ! blend in logT
      88            0 :                alfa = (logT - logT_lo)/(logT_hi - logT_lo)
      89            0 :                d_alfa_dlogT = 1/(logT_hi - logT_lo)
      90              :             else  ! blend in logRho
      91            0 :                alfa = (logRho_hi - logRho)/(logRho_hi - logRho_lo)
      92            0 :                d_alfa_dlogRho = -1d0/(logRho_hi - logRho_lo)
      93              :             end if
      94              :          end if
      95              : 
      96            0 :       end subroutine Get_PC_alfa
      97              : 
      98              : 
      99            0 :       subroutine get_PC_for_eosdt( &
     100              :             handle, dbg, Z, X, abar, zbar, &
     101            0 :             species, chem_id, net_iso, xa, &
     102              :             rho, logRho, T, logT, remaining_fraction, &
     103            0 :             res, d_dlnd, d_dlnT, d_dxa, &
     104              :             skip, ierr)
     105              :          integer, intent(in) :: handle
     106              :          logical, intent(in) :: dbg
     107              :          real(dp), intent(in) :: &
     108              :             Z, X, abar, zbar, remaining_fraction
     109              :          integer, intent(in) :: species
     110              :          integer, pointer :: chem_id(:), net_iso(:)
     111              :          real(dp), intent(in) :: xa(:)
     112              :          real(dp), intent(in) :: rho, logRho, T, logT
     113              :          real(dp), intent(inout), dimension(nv) :: &
     114              :             res, d_dlnd, d_dlnT
     115              :          real(dp), intent(inout), dimension(nv, species) :: d_dxa
     116              :          logical, intent(out) :: skip
     117              :          integer, intent(out) :: ierr
     118              :          type (EoS_General_Info), pointer :: rq
     119            0 :          rq => eos_handles(handle)
     120              :          call Get_PC_Results(rq, &
     121              :             Z, X, abar, zbar, &
     122              :             species, chem_id, net_iso, xa, &
     123              :             rho, logRho, T, logT, &
     124            0 :             res, d_dlnd, d_dlnT, d_dxa, ierr)
     125            0 :          skip = .false.
     126              : 
     127              :          ! zero latent heat information
     128            0 :          res(i_latent_ddlnT:i_latent_ddlnRho) = 0d0
     129            0 :          d_dlnT(i_latent_ddlnT:i_latent_ddlnRho) = 0d0
     130            0 :          d_dlnd(i_latent_ddlnT:i_latent_ddlnRho) = 0d0
     131              : 
     132              :          ! zero all components
     133            0 :          res(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
     134            0 :          d_dlnd(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
     135            0 :          d_dlnT(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
     136              : 
     137              :          ! mark this one
     138            0 :          res(i_frac_PC) = 1.0d0
     139              : 
     140            0 :       end subroutine get_PC_for_eosdt
     141              : 
     142              : 
     143            0 :       subroutine Get_PC_Results( &
     144              :             rq, Z, X, abar, zbar, &
     145            0 :             species, chem_id, net_iso, xa, &
     146              :             Rho, logRho, T, logT, &
     147            0 :             res, d_dlnRho_c_T, d_dlnT_c_Rho, d_dxa, ierr)
     148              :          use pc_eos
     149              :          use chem_def, only: chem_isos
     150              :          type (EoS_General_Info), pointer :: rq
     151              :          real(dp), intent(in) :: Z, X, abar, zbar
     152              :          integer, intent(in) :: species
     153              :          integer, pointer :: chem_id(:), net_iso(:)
     154              :          real(dp), intent(in) :: xa(:)
     155              :          real(dp), intent(in) :: Rho, logRho, T, logT
     156              :          real(dp), intent(inout) :: res(:)  ! (nv)
     157              :          real(dp), intent(inout) :: d_dlnRho_c_T(:)  ! (nv)
     158              :          real(dp), intent(inout) :: d_dlnT_c_Rho(:)  ! (nv)
     159              :          real(dp), intent(inout) :: d_dxa(:,:)  ! (nv, species)
     160              :          integer, intent(out) :: ierr
     161              : 
     162            0 :          real(dp) :: start_crystal, full_crystal
     163            0 :          real(dp), dimension(species) :: AY, AZion, ACMI
     164              :          integer :: i, j
     165              : 
     166              :          include 'formats'
     167              : 
     168            0 :          ierr = 0
     169            0 :          AZion(1:species) = chem_isos% Z(chem_id(1:species))
     170            0 :          ACMI(1:species) = chem_isos% W(chem_id(1:species))  ! this really is atomic weight.
     171            0 :          do j=1,species
     172            0 :             if (xa(j) < rq% mass_fraction_limit_for_PC) then
     173            0 :                AY(j) = 0
     174              :             else
     175            0 :                AY(j) = xa(j)/ACMI(j)
     176              :             end if
     177              :          end do
     178              : 
     179            0 :          start_crystal = rq% PC_Gamma_start_crystal
     180            0 :          full_crystal = rq% PC_Gamma_full_crystal
     181              : 
     182              : 
     183            0 :          call do1(.false.,Rho,T,start_crystal,full_crystal,res,d_dlnT_c_Rho,d_dlnRho_c_T,ierr)
     184            0 :          if (ierr /= 0) return
     185              : 
     186              :          ! composition derivatives not provided
     187            0 :          d_dxa = 0
     188              : 
     189            0 :          if (is_bad(res(i_lnS))) then
     190            0 :             ierr = -1
     191            0 :             write(*,1) 'res(i_lnS), logRho, logT', res(i_lnS), logRho, logT
     192            0 :             call mesa_error(__FILE__,__LINE__,'Get_PC_Results')
     193              :          end if
     194              : 
     195              :          contains
     196              : 
     197            0 :          subroutine do1(show,RHO_real,T_real,start_crystal,full_crystal,res,d_dlnT_c_Rho,d_dlnRho_c_T,ierr)
     198              :             logical, intent(in) :: show
     199              :             real(dp), intent(in) :: start_crystal, full_crystal
     200              :             real(dp), intent(in) :: RHO_real, T_real
     201              :             real(dp), intent(out) :: res(:), d_dlnT_c_Rho(:), d_dlnRho_c_T(:)  ! (nv)
     202              :             integer, intent(out) :: ierr
     203              : 
     204              :             integer :: j, LIQSOL
     205              :             type(auto_diff_real_2var_order1) :: dsp, dse, dpe, &
     206              :                DENS,GAMI,CHI,TPT,GAMImean,TEMP, &
     207              :                PnkT,UNkT,SNk,CVNkt,CV,CHIR,CHIT,Tnk,P,Cp,gamma1,gamma3,grad_ad, N, &
     208              :                Prad,Pgas,PRADnkT,dE_dRho,dS_dT,dS_dRho,mu,lnfree_e, lnPgas, lnE, lnS, RHO, T
     209              :             type(auto_diff_real_2var_order1) :: phase
     210            0 :             real(dp) :: Zmean,CMImean,Z2mean
     211              :             real(dp), parameter :: UN_T6=0.3157746d0
     212              : 
     213              :             include 'formats'
     214              : 
     215            0 :             ierr = 0
     216              : 
     217            0 :             T = T_real
     218            0 :             T%d1val1 = 1d0
     219              : 
     220            0 :             RHO = RHO_real
     221            0 :             RHO%d1val2 = 1d0
     222              : 
     223            0 :             TEMP=T*1d-6/UN_T6  ! T [au]
     224              : 
     225            0 :             if (show) then
     226            0 :                write(*,1) 'RHO', RHO
     227            0 :                write(*,1) 'TEMP', TEMP
     228            0 :                write(*,1) 'start_crystal', start_crystal
     229            0 :                write(*,1) 'full_crystal', full_crystal
     230            0 :                write(*,1) 'AZion(1:species)', AZion(1:species)
     231            0 :                write(*,1) 'ACMI(1:species)', ACMI(1:species)
     232            0 :                write(*,1) 'AY(1:species)', AY(1:species)
     233            0 :                write(*,1) 'xa(1:species)', xa(1:species)
     234              :             end if
     235              : 
     236              :             call MELANGE9( &
     237              :                species,AY,AZion,ACMI,RHO,TEMP, &
     238              :                start_crystal,full_crystal,PRADnkT, &
     239              :                DENS,Zmean,CMImean,Z2mean,GAMImean,CHI,TPT,LIQSOL, &
     240            0 :                PnkT,UNkT,SNk,CVNkt,CHIR,CHIT,ierr)
     241              : 
     242              :             ! calculate phase information
     243            0 :             if (GAMImean<start_crystal) then  ! liquid
     244            0 :                phase = 0d0
     245            0 :             else if (GAMImean>full_crystal) then  ! solid
     246            0 :                phase = 1d0
     247              :             else  ! blend of liquid and solid
     248            0 :                phase = (GAMImean - start_crystal)/(full_crystal - start_crystal)  ! 1 for solid, 0 for liquid
     249              :             end if
     250              : 
     251            0 :             if (ierr /= 0) then
     252            0 :                return
     253              :                write(*,1) 'RHO', RHO
     254              :                write(*,1) 'T', T
     255              :                write(*,1) 'logRho', log10(RHO)
     256              :                write(*,1) 'logT', log10(T)
     257              :                write(*,*) 'ierr from MELANGE9'
     258              :                call mesa_error(__FILE__,__LINE__,'debug eos')
     259              :             end if
     260              : 
     261            0 :             if (show) then
     262            0 :                write(*,1) 'PRADnkT', PRADnkT
     263            0 :                write(*,1) 'DENS', DENS
     264            0 :                write(*,1) 'Zmean', Zmean
     265            0 :                write(*,1) 'CMImean', CMImean
     266            0 :                write(*,1) 'Z2mean', Z2mean
     267            0 :                write(*,1) 'GAMI', GAMImean
     268            0 :                write(*,1) 'CHI', CHI
     269            0 :                write(*,1) 'TPT', TPT
     270            0 :                write(*,1) 'PnkT', PnkT
     271            0 :                write(*,1) 'UNkT', UNkT
     272            0 :                write(*,1) 'SNk', SNk
     273            0 :                write(*,1) 'CV', CVNkt
     274            0 :                write(*,1) 'CHIR', CHIR
     275            0 :                write(*,1) 'CHIT', CHIT
     276            0 :                write(*,'(A)')
     277              :             end if
     278              : 
     279            0 :             Tnk=8.31447d7/CMImean*RHO*T  ! n_i kT [erg/cc]
     280            0 :             Pgas = PnkT*Tnk
     281            0 :             if (rq% include_radiation) then
     282              :                ! results from MELANGE9 do not include radiation.  add it now.
     283            0 :                CHIT=CHIT*(PnkT/(PnkT+PRADnkT))  + 4.d0*PRADnkT/(PnkT+PRADnkT)
     284            0 :                CHIR=CHIR*(PnkT/(PnkT+PRADnkT))
     285            0 :                PnkT=PnkT+PRADnkT
     286            0 :                UNkT=UNkT+3.d0*PRADnkT
     287            0 :                SNk=SNk+4.d0*PRADnkT
     288            0 :                CVNkt=CVNkt+12.d0*PRADnkT
     289              :             end if
     290            0 :             P = PnkT*Tnk
     291            0 :             N = 1/(abar*amu)
     292            0 :             CV = CVNkt*N*kerg
     293            0 :             gamma3 = 1d0 + P/rho * chit/(T*CV)
     294            0 :             gamma1 = chit*(gamma3-1d0) + chir
     295            0 :             grad_ad = (gamma3-1d0)/gamma1
     296            0 :             Cp = CV * gamma1/chir
     297            0 :             dE_dRho = (1d0-chiT)*P/(rho*rho)
     298            0 :             dS_dT = CV/T
     299            0 :             dS_dRho = -P*chiT/(rho*rho * T)
     300            0 :             mu = abar / (1d0 + zbar)
     301            0 :             lnfree_e = log(zbar/abar)  ! for complete ionization
     302            0 :             lnPgas = log(Pgas)
     303            0 :             lnE = safe_log(UNkt*N*kerg*T)
     304            0 :             lnS = safe_log(SNk*N*kerg)
     305              : 
     306              : 
     307            0 :             res(i_lnPgas) = lnPgas % val
     308            0 :             res(i_lnE) = lnE % val
     309            0 :             res(i_lnS) = lnS % val
     310            0 :             res(i_grad_ad) = grad_ad % val
     311            0 :             res(i_chiRho) = CHIR % val
     312            0 :             res(i_chiT) = CHIT % val
     313            0 :             res(i_Cp) = Cp % val
     314            0 :             res(i_Cv) = CV % val
     315            0 :             res(i_dE_dRho) = dE_dRho % val
     316            0 :             res(i_dS_dT) = dS_dT % val
     317            0 :             res(i_dS_dRho) = dS_dRho % val
     318            0 :             res(i_mu) = mu % val
     319            0 :             res(i_lnfree_e) = lnfree_e % val
     320            0 :             res(i_gamma1) = gamma1 % val
     321            0 :             res(i_gamma3) = gamma3 % val
     322            0 :             res(i_eta) = CHI % val
     323            0 :             res(i_phase) = phase % val
     324              : 
     325            0 :             d_dlnT_c_Rho(i_lnPgas) = lnPgas % d1val1 * T % val
     326            0 :             d_dlnT_c_Rho(i_lnE) = lnE % d1val1 * T % val
     327            0 :             d_dlnT_c_Rho(i_lnS) = lnS % d1val1 * T % val
     328            0 :             d_dlnT_c_Rho(i_grad_ad) = grad_ad % d1val1 * T % val
     329            0 :             d_dlnT_c_Rho(i_chiRho) = CHIR % d1val1 * T % val
     330            0 :             d_dlnT_c_Rho(i_chiT) = CHIT % d1val1 * T % val
     331            0 :             d_dlnT_c_Rho(i_Cp) = Cp % d1val1 * T % val
     332            0 :             d_dlnT_c_Rho(i_Cv) = CV % d1val1 * T % val
     333            0 :             d_dlnT_c_Rho(i_dE_dRho) = dE_dRho % d1val1 * T % val
     334            0 :             d_dlnT_c_Rho(i_dS_dT) = dS_dT % d1val1 * T % val
     335            0 :             d_dlnT_c_Rho(i_dS_dRho) = dS_dRho % d1val1 * T % val
     336            0 :             d_dlnT_c_Rho(i_mu) = mu % d1val1 * T % val
     337            0 :             d_dlnT_c_Rho(i_lnfree_e) = lnfree_e % d1val1 * T % val
     338            0 :             d_dlnT_c_Rho(i_gamma1) = gamma1 % d1val1 * T % val
     339            0 :             d_dlnT_c_Rho(i_gamma3) = gamma3 % d1val1 * T % val
     340            0 :             d_dlnT_c_Rho(i_eta) = CHI % d1val1 * T % val
     341            0 :             d_dlnT_c_Rho(i_phase) = phase % d1val1 * T % val
     342              : 
     343            0 :             d_dlnRho_c_T(i_lnPgas) = lnPgas % d1val2 * RHO % val
     344            0 :             d_dlnRho_c_T(i_lnE) = lnE % d1val2 * RHO % val
     345            0 :             d_dlnRho_c_T(i_lnS) = lnS % d1val2 * RHO % val
     346            0 :             d_dlnRho_c_T(i_grad_ad) = grad_ad % d1val2 * RHO % val
     347            0 :             d_dlnRho_c_T(i_chiRho) = CHIR % d1val2 * RHO % val
     348            0 :             d_dlnRho_c_T(i_chiT) = CHIT % d1val2 * RHO % val
     349            0 :             d_dlnRho_c_T(i_Cp) = Cp % d1val2 * RHO % val
     350            0 :             d_dlnRho_c_T(i_Cv) = CV % d1val2 * RHO % val
     351            0 :             d_dlnRho_c_T(i_dE_dRho) = dE_dRho % d1val2 * RHO % val
     352            0 :             d_dlnRho_c_T(i_dS_dT) = dS_dT % d1val2 * RHO % val
     353            0 :             d_dlnRho_c_T(i_dS_dRho) = dS_dRho % d1val2 * RHO % val
     354            0 :             d_dlnRho_c_T(i_mu) = mu % d1val2 * RHO % val
     355            0 :             d_dlnRho_c_T(i_lnfree_e) = lnfree_e % d1val2 * RHO % val
     356            0 :             d_dlnRho_c_T(i_gamma1) = gamma1 % d1val2 * RHO % val
     357            0 :             d_dlnRho_c_T(i_gamma3) = gamma3 % d1val2 * RHO % val
     358            0 :             d_dlnRho_c_T(i_eta) = CHI % d1val2 * RHO % val
     359            0 :             d_dlnRho_c_T(i_phase) = phase % d1val2 * RHO % val
     360              : 
     361            0 :          end subroutine do1
     362              : 
     363              :       end subroutine Get_PC_Results
     364              : 
     365              :       end module eospc_eval
        

Generated by: LCOV version 2.0-1