LCOV - code coverage report
Current view: top level - atm/test/src - test_atm_support.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.9 % 229 215
Test Date: 2025-05-08 18:23:42 Functions: 100.0 % 8 8

            Line data    Source code
       1              : module test_atm_support
       2              : 
       3              :    use const_def
       4              :    use math_lib
       5              :    use atm_def
       6              :    use atm_lib
       7              :    use chem_lib, only: composition_info
       8              :    use chem_def
       9              :    use eos_def
      10              :    use eos_lib
      11              :    use kap_def
      12              :    use kap_lib
      13              : 
      14              :    implicit none
      15              : 
      16              :    logical, parameter :: SKIP_PARTIALS = .TRUE.
      17              : 
      18              :    logical :: test_verbosely
      19              :    integer :: eos_handle, kap_handle
      20              :    real(dp) :: cgrav, Pextra_factor
      21              :    ! composition info
      22              :    integer, parameter :: species = 7
      23              :    integer, pointer :: chem_id(:), net_iso(:)
      24              :    real(dp) :: X, Y, Z, XC, XN, XO, xa(species), abar, zbar, z53bar
      25              : 
      26              :    integer :: ierr, max_iters, max_steps, iters
      27              :    real(dp) :: logg, Teff, M, R, L, kap_guess, tau, tau_base, tau_phot, &
      28              :                lnT, dlnT_dL, dlnT_dlnR, dlnT_dlnM, &
      29              :                lnP, dlnP_dL, dlnP_dlnR, dlnP_dlnM, &
      30              :                atol, rtol, kap, T, err, P, Prad, &
      31              :                dlnT_dlnkap, dlnP_dlnkap, &
      32              :                logTeff, log_gsurf, log_Rsurf, log_M, g, &
      33              :                T_eq, kap_v, gamma, T_int
      34              : 
      35              : contains
      36              : 
      37         6218 :    subroutine do_test_atm( &
      38              :       test_verbosely_in, cgrav_in, eos_handle_in, kap_handle_in)
      39              :       logical, intent(in) :: test_verbosely_in
      40              :       real(dp), intent(in) :: cgrav_in
      41              :       integer, intent(in) :: eos_handle_in, kap_handle_in
      42              : 
      43            2 :       test_verbosely = test_verbosely_in
      44            2 :       cgrav = cgrav_in
      45            2 :       eos_handle = eos_handle_in
      46            2 :       kap_handle = kap_handle_in
      47              : 
      48            2 :       call test_table(ATM_TABLE_TAU_1M1, 'tau=0.1')
      49            2 :       call test_table(ATM_TABLE_TAU_1, 'tau=1')
      50            2 :       call test_table(ATM_TABLE_TAU_10, 'tau=10')
      51            2 :       call test_table(ATM_TABLE_TAU_100, 'tau=100')
      52              : 
      53            2 :       call test_table(ATM_TABLE_WD_TAU_25, 'WD tau=25')
      54            2 :       call test_table(ATM_TABLE_DB_WD_TAU_25, 'DB WD tau=25')
      55            2 :       call test_table(ATM_TABLE_PHOTOSPHERE, 'photosphere')
      56              : 
      57            2 :       call test_T_tau_varying(ATM_T_TAU_EDDINGTON, 'Eddington', -1._dp)
      58            2 :       call test_T_tau_varying(ATM_T_TAU_KRISHNA_SWAMY, 'Krishna-Swamy', -1._dp)
      59            2 :       call test_T_tau_varying(ATM_T_TAU_SOLAR_HOPF, 'solar Hopf', -1._dp)
      60            2 :       call test_T_tau_varying(ATM_T_TAU_TRAMPEDACH_SOLAR, 'Trampedach solar', -1._dp)
      61            2 :       call test_T_tau_varying(ATM_T_TAU_EDDINGTON, 'Eddington', 100._dp)
      62              : 
      63            2 :       call test_T_tau_uniform('fixed', 100._dp)
      64            2 :       call test_T_tau_uniform('iterated', 150._dp)
      65              : 
      66            2 :       call test_irradiated()
      67              : 
      68            2 :    end subroutine do_test_atm
      69              : 
      70              :    !****
      71              : 
      72           14 :    subroutine test_table(table_id, label)
      73              : 
      74              :       integer, intent(in)      :: table_id
      75              :       character(*), intent(in) :: label
      76              : 
      77              :       include 'formats'
      78              : 
      79           14 :       ierr = 0
      80              : 
      81           14 :       if (test_verbosely) then
      82            7 :          write (*, *)
      83            7 :          write (*, *) 'test_table: ', label
      84              :       end if
      85              : 
      86           14 :       if (table_id == ATM_TABLE_WD_TAU_25) then
      87            2 :          logg = 7.1d0
      88            2 :          Teff = 5000
      89            2 :          M = 0.8d0*Msun
      90            2 :          R = sqrt(cgrav*M/exp10(logg))
      91              :          !write(*,*) 'R/Rsun', R/Rsun
      92            2 :          L = pi*crad*clight*R*R*Teff*Teff*Teff*Teff
      93              :          !write(*,*) 'L/Lsun', L/Lsun
      94           12 :       elseif (table_id == ATM_TABLE_DB_WD_TAU_25) then
      95            2 :          logg = 8.0d0
      96            2 :          Teff = 25000
      97            2 :          M = 0.8d0*Msun
      98            2 :          R = sqrt(cgrav*M/exp10(logg))
      99              :          !write(*,*) 'R/Rsun', R/Rsun
     100            2 :          L = pi*crad*clight*R*R*Teff*Teff*Teff*Teff
     101              :          !write(*,*) 'L/Lsun', L/Lsun    else
     102              :       else
     103           10 :          M = Msun
     104           10 :          R = Rsun
     105           10 :          L = Lsun
     106           10 :          Teff = atm_Teff(L, R)
     107              :       end if
     108              : 
     109           14 :       Z = 0.02d0
     110              : 
     111              :       call atm_eval_table( &
     112              :          L, R, M, cgrav, table_id, Z, SKIP_PARTIALS, &
     113              :          Teff, &
     114              :          lnT, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     115              :          lnP, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap, &
     116           14 :          ierr)
     117           14 :       if (ierr /= 0) then
     118            0 :          if (test_verbosely) write (*, *) 'failed in atm_eval_table'
     119            0 :          call mesa_error(__FILE__, __LINE__)
     120              :       end if
     121              : 
     122           14 :       T = exp(lnT)
     123           14 :       P = exp(lnP)
     124              : 
     125           14 :       Prad = radiation_pressure(T)
     126              : 
     127           14 :       if (test_verbosely) write (*, *)
     128           14 :       if (test_verbosely) write (*, '(99a16)') &
     129            7 :          'T', 'log_T', 'log P', 'M/Msun', 'L/Lsun', 'R/Rsun', 'logPgas'
     130           14 :       if (test_verbosely) write (*, '(i16,99f16.8)') &
     131            7 :          floor(0.5d0 + T), lnT/ln10, log10(P), M/Msun, L/Lsun, R/Rsun, log10(P - Prad)
     132           14 :       if (test_verbosely) write (*, *)
     133              : 
     134           14 :    end subroutine test_table
     135              : 
     136              :    !****
     137              : 
     138           10 :    subroutine test_T_tau_varying(T_tau_id, label, tau_base_in)
     139              : 
     140              :       integer, intent(in)      :: T_tau_id
     141              :       character(*), intent(in) :: label
     142              :       real(dp), intent(in)     :: tau_base_in
     143              : 
     144           10 :       real(dp) :: errtol
     145              :       integer  :: max_steps
     146              : 
     147              :       include 'formats'
     148              : 
     149           10 :       ierr = 0
     150              : 
     151           10 :       if (tau_base_in < 0._dp) then
     152            8 :          call atm_get_T_tau_base(T_tau_id, tau_base, ierr)
     153            8 :          if (ierr /= 0) then
     154            0 :             if (test_verbosely) write (*, *) 'failed in atm_eval_T_tau_varying'
     155            0 :             return
     156              :          end if
     157              :       else
     158            2 :          tau_base = tau_base_in
     159              :       end if
     160              : 
     161           10 :       if (test_verbosely) then
     162            5 :          write (*, *)
     163            5 :          write (*, *) 'test_T_tau_varying: ', label
     164              :       end if
     165              : 
     166              :       ! TEST SOLAR VALUES
     167           10 :       logTeff = log10(5776d0)
     168           10 :       log_gsurf = log10(cgrav*Msun/(Rsun*Rsun))
     169           10 :       log_Rsurf = log10(Rsun)
     170           10 :       log_M = log10(Msun)
     171              : 
     172           10 :       Z = 0.02d0
     173           10 :       X = 0.70d0
     174           10 :       XC = 3.2724592105263235d-03
     175           10 :       XN = 9.5023842105263292d-04
     176           10 :       XO = 8.8218000000000601d-03
     177           10 :       call set_composition()
     178              : 
     179           10 :       R = exp10(log_Rsurf)
     180           10 :       M = exp10(log_M)
     181              : 
     182           10 :       g = exp10(log_gsurf)
     183           10 :       Teff = exp10(logTeff)
     184           10 :       L = pi*crad*clight*R*R*Teff*Teff*Teff*Teff
     185              : 
     186           10 :       errtol = 1.E-9_dp
     187           10 :       max_steps = 500
     188              : 
     189              :       call atm_eval_T_tau_varying( &
     190              :          tau_base, L, R, M, cgrav, &
     191              :          T_tau_id, eos_proc, kap_proc, &
     192              :          errtol, max_steps, SKIP_PARTIALS, &
     193              :          Teff, &
     194              :          lnT, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     195              :          lnP, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap, &
     196           10 :          ierr)
     197           10 :       if (ierr /= 0) then
     198            0 :          if (test_verbosely) write (*, *) 'failed in atm_eval_T_tau_varying'
     199            0 :          call mesa_error(__FILE__, __LINE__)
     200              :       end if
     201              : 
     202           10 :       T = exp(lnT)
     203           10 :       P = exp(lnP)
     204              : 
     205           10 :       if (test_verbosely) write (*, *)
     206           10 :       if (test_verbosely) write (*, '(99a16)') 'T', 'log T', 'log P', 'M/Msun', 'L/Lsun', 'X', 'Z'
     207           10 :       if (test_verbosely) write (*, '(i16,99f16.8)') &
     208            5 :          floor(0.5d0 + T), log10(T), log10(P), M/Msun, L/Lsun, X, Z
     209           10 :       if (test_verbosely) write (*, *)
     210              : 
     211           10 :       deallocate (chem_id, net_iso)
     212              : 
     213              :    end subroutine test_T_tau_varying
     214              : 
     215              :    !****
     216              : 
     217            4 :    subroutine test_T_tau_uniform(T_tau_opacity, tau_base_in)
     218              : 
     219              :       character(*), intent(in) :: T_tau_opacity
     220              :       real(dp), intent(in)     :: tau_base_in
     221              : 
     222            4 :       real(dp) :: tau_base
     223            4 :       real(dp) :: errtol
     224              : 
     225              :       include 'formats'
     226              : 
     227            4 :       if (test_verbosely) then
     228            2 :          write (*, *)
     229            2 :          write (*, *) 'test_T_tau_uniform: ', TRIM(T_tau_opacity)
     230              :       end if
     231              : 
     232            4 :       tau_base = tau_base_in
     233            4 :       if (tau_base <= 0._dp) then
     234            0 :          tau_base = 2._dp/3._dp
     235              :       end if
     236              : 
     237            4 :       Pextra_factor = 1._dp
     238              : 
     239            2 :       select case (T_tau_opacity)
     240              : 
     241              :       case ('fixed')
     242              : 
     243            2 :          M = 1.9892000000000002D+32
     244            2 :          R = 6.3556231577545586D+10
     245            2 :          L = 2.4015399190199118D+32
     246            2 :          Teff = atm_Teff(L, R)
     247              : 
     248            2 :          kap_guess = 5.8850802481174469D-02
     249              : 
     250            2 :          max_iters = 0
     251              : 
     252              :       case ('iterated')
     253              : 
     254            2 :          logTeff = log10(5776._dp)
     255            2 :          log_gsurf = log10(cgrav*Msun/(Rsun*Rsun))
     256            2 :          log_Rsurf = log10(Rsun)
     257            2 :          log_M = log10(Msun)
     258              : 
     259            2 :          R = exp10(log_Rsurf)
     260            2 :          M = exp10(log_M)
     261            2 :          Teff = exp10(logTeff)
     262            2 :          L = pi*crad*clight*R*R*Teff*Teff*Teff*Teff
     263              : 
     264            2 :          kap_guess = 0.5d0
     265              : 
     266            2 :          max_iters = 30
     267              : 
     268              :       case default
     269              : 
     270            0 :          write (*, *) 'unknown value for T_tau_opacity '//trim(T_tau_opacity)
     271              : 
     272            4 :          stop
     273              : 
     274              :       end select
     275              : 
     276            4 :       Z = 0.02d0
     277            4 :       X = 0.70d0
     278            4 :       XC = 3.2724592105263235d-03
     279            4 :       XN = 9.5023842105263292d-04
     280            4 :       XO = 8.8218000000000601d-03
     281            4 :       call set_composition()
     282              : 
     283            4 :       errtol = 1.E-6_dp
     284              : 
     285              :       call atm_eval_T_tau_uniform( &
     286              :          tau_base, L, R, M, cgrav, kap_guess, Pextra_factor, &
     287              :          ATM_T_TAU_EDDINGTON, eos_proc, kap_proc, errtol, max_iters, SKIP_PARTIALS, &
     288              :          Teff, kap, &
     289              :          lnT, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     290              :          lnP, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap, &
     291            4 :          ierr)
     292            4 :       if (ierr /= 0) then
     293            0 :          if (test_verbosely) write (*, *) 'failed in atm_eval_T_tau_uniform'
     294            0 :          call mesa_error(__FILE__, __LINE__)
     295              :       end if
     296            4 :       if (test_verbosely) write (*, 1) 'atm_get_grey logP surf', lnP/ln10
     297            4 :       if (test_verbosely) write (*, 1) 'atm_get_grey logT surf', lnT/ln10
     298            4 :       if (test_verbosely) write (*, 1) 'atm_get_grey tau_phot', tau_base
     299            4 :       if (test_verbosely) write (*, *)
     300              : 
     301            4 :       deallocate (chem_id, net_iso)
     302              : 
     303            4 :    end subroutine test_T_tau_uniform
     304              : 
     305              :    !****
     306              : 
     307            6 :    subroutine test_irradiated()
     308              : 
     309            2 :       real(dp) :: errtol
     310              :       type(Kap_General_Info), pointer :: rq
     311              : 
     312              :       include 'formats'
     313              : 
     314            2 :       if (test_verbosely) then
     315            1 :          write (*, *)
     316            1 :          write (*, *) 'test_irradiated'
     317              :       end if
     318              : 
     319            2 :       ierr = 0
     320              : 
     321            2 :       X = 0.70d0
     322            2 :       Z = 1d-2
     323            2 :       XC = 3.2724592105263235d-03
     324            2 :       XN = 9.5023842105263292d-04
     325            2 :       XO = 8.8218000000000601d-03
     326              : 
     327            2 :       call set_composition()
     328              : 
     329              :       ! at these conditions, the appropriate lowT opacity table is Freedman11
     330              :       ! this is around logR = 3.5, way off the default tables (max logR = 1)
     331            2 :       call kap_ptr(kap_handle, rq, ierr)
     332            2 :       if (ierr /= 0) return
     333            2 :       rq%kap_lowT_option = kap_lowT_Freedman11
     334              : 
     335              :       ! must set up tables again after changing options
     336            2 :       call kap_setup_tables(kap_handle, ierr)
     337              : 
     338            2 :       errtol = 1.E-6_dp
     339            2 :       max_iters = 30
     340              : 
     341            2 :       T_eq = 1000.
     342            2 :       kap_v = 4.E-3_dp
     343            2 :       kap_guess = 1.5d-2
     344            2 :       gamma = 0._dp
     345            2 :       P = 1d6
     346            2 :       M = 1.5d0*M_jupiter
     347              :       tau = 10  ! just a guess for use in getting R
     348            2 :       R = sqrt(cgrav*M*tau/(P*kap_guess))  ! g = P*kap/tau = G*M/R^2
     349            2 :       T_int = 900
     350            2 :       L = pi*crad*clight*R*R*T_int*T_int*T_int*T_int
     351              : 
     352              :       call atm_eval_irradiated( &
     353              :          L, R, M, cgrav, T_eq, P, kap_guess, kap_v, gamma, &
     354              :          eos_proc, kap_proc, errtol, max_iters, SKIP_PARTIALS, &
     355              :          Teff, kap, tau, &
     356              :          lnT, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     357            2 :          ierr)
     358            2 :       if (ierr /= 0) then
     359            0 :          if (test_verbosely) write (*, *) 'bad return from atm_eval_irradiated'
     360            0 :          call mesa_error(__FILE__, __LINE__)
     361              :       end if
     362              : 
     363            2 :       if (test_verbosely) write (*, *)
     364            2 :       if (test_verbosely) write (*, 1) 'test_grey_irradiated: kap', kap
     365            2 :       if (test_verbosely) write (*, 1) 'M/M_jupiter', M/M_jupiter
     366            2 :       if (test_verbosely) write (*, 1) 'R/R_jupiter', R/R_jupiter
     367            2 :       if (test_verbosely) write (*, 1) 'R/Rsun', R/Rsun
     368            2 :       if (test_verbosely) write (*, 1) 'kap_v', kap_v
     369            2 :       if (test_verbosely) write (*, 1) 'P', P
     370            2 :       if (test_verbosely) write (*, *)
     371              : 
     372            2 :       if (test_verbosely) write (*, 1) 'tau', tau
     373            2 :       if (test_verbosely) write (*, 1) 'Teff', Teff
     374            2 :       if (test_verbosely) write (*, 1) 'T_eq', T_eq
     375            2 :       if (test_verbosely) write (*, 1) 'T_int', T_int
     376            2 :       if (test_verbosely) write (*, 1) 'T', exp(lnT)
     377            2 :       if (test_verbosely) write (*, 1) 'logT', lnT/ln10
     378            2 :       if (test_verbosely) write (*, *)
     379              : 
     380            2 :       deallocate (chem_id, net_iso)
     381              : 
     382              :    end subroutine test_irradiated
     383              : 
     384              :    !****
     385              : 
     386           16 :    subroutine set_composition()
     387           16 :       real(dp) :: xz, z2bar, ye, mass_correction, sumx, &
     388          384 :                   dabar_dx(species), dzbar_dx(species), dmc_dx(species)
     389              :       integer :: i
     390              :       type(Kap_General_Info), pointer :: rq
     391           16 :       call kap_ptr(kap_handle, rq, ierr)
     392           16 :       rq%Zbase = Z
     393           16 :       Y = 1 - (X + Z)
     394           16 :       allocate (chem_id(species), net_iso(num_chem_isos), stat=ierr)
     395           16 :       if (ierr /= 0) then
     396            0 :          write (*, *) 'allocate failed'
     397            0 :          call mesa_error(__FILE__, __LINE__)
     398              :       end if
     399          128 :       chem_id(:) = [ih1, ihe4, ic12, in14, io16, ine20, img24]
     400       125712 :       net_iso(:) = 0
     401          128 :       forall (i=1:species) net_iso(chem_id(i)) = i
     402          128 :       xa(:) = [X, Y, xc, xn, xo, 0d0, 0d0]
     403          128 :       xa(species) = 1 - sum(xa(:))
     404              :       call composition_info( &
     405              :          species, chem_id, xa, X, Y, xz, abar, zbar, z2bar, z53bar, ye, &
     406           16 :          mass_correction, sumx, dabar_dx, dzbar_dx, dmc_dx)
     407           16 :    end subroutine set_composition
     408              : 
     409              :    !****
     410              : 
     411         6216 :    subroutine eos_proc( &
     412              :       lnP, lnT, &
     413         6216 :       lnRho, res, dres_dlnRho, dres_dlnT, &
     414              :       ierr)
     415              : 
     416              :       use eos_def, only: num_eos_basic_results
     417              :       use eos_lib, only: eosPT_get, radiation_pressure
     418              : 
     419              :       real(dp), intent(in)  :: lnP
     420              :       real(dp), intent(in)  :: lnT
     421              :       real(dp), intent(out) :: lnRho
     422              :       real(dp), intent(out) :: res(:)
     423              :       real(dp), intent(out) :: dres_dlnRho(:)
     424              :       real(dp), intent(out) :: dres_dlnT(:)
     425              :       integer, intent(out)  :: ierr
     426              : 
     427         6216 :       real(dp) :: T, P, Prad, Pgas, logPgas, rho
     428         6216 :       real(dp) :: logRho, dlnRho_dlnPgas, dlnRho_dlnT
     429       136752 :       real(dp), dimension(num_eos_d_dxa_results, species) :: dres_dxa
     430              : 
     431         6216 :       T = exp(lnT)
     432         6216 :       P = exp(lnP)
     433              : 
     434         6216 :       Prad = radiation_pressure(T)
     435         6216 :       Pgas = max(1E-99_dp, P - Prad)
     436         6216 :       logPgas = log10(Pgas)
     437              : 
     438              :       call eosPT_get( &
     439              :          eos_handle, &
     440              :          species, chem_id, net_iso, xa, &
     441              :          Pgas, logPgas, T, lnT/ln10, &
     442              :          Rho, logRho, dlnRho_dlnPgas, dlnRho_dlnT, &
     443         6216 :          res, dres_dlnRho, dres_dlnT, dres_dxa, ierr)
     444              : 
     445         6216 :       lnRho = logRho*ln10
     446              : 
     447         6216 :    end subroutine eos_proc
     448              : 
     449              :    !****
     450              : 
     451         6216 :    subroutine kap_proc( &
     452         6216 :       lnRho, lnT, res, dres_dlnRho, dres_dlnT, &
     453              :       kap, dlnkap_dlnRho, dlnkap_dlnT, &
     454              :       ierr)
     455              : 
     456         6216 :       use kap_def, only: num_kap_fracs
     457              :       use kap_lib, only: kap_get
     458              :       use eos_def, only: i_lnfree_e, i_eta
     459              : 
     460              :       real(dp), intent(in)  :: lnRho
     461              :       real(dp), intent(in)  :: lnT
     462              :       real(dp), intent(in)  :: res(:)
     463              :       real(dp), intent(in)  :: dres_dlnRho(:)
     464              :       real(dp), intent(in)  :: dres_dlnT(:)
     465              :       real(dp), intent(out) :: kap
     466              :       real(dp), intent(out) :: dlnkap_dlnRho
     467              :       real(dp), intent(out) :: dlnkap_dlnT
     468              :       integer, intent(out)  :: ierr
     469              : 
     470        80808 :       real(dp) :: kap_fracs(num_kap_fracs), dlnkap_dxa(species)
     471              : 
     472              :       call kap_get( &
     473              :          kap_handle, species, chem_id, net_iso, xa, &
     474         6216 :          lnRho/ln10, lnT/ln10, res(i_lnfree_e), dres_dlnRho(i_lnfree_e), dres_dlnT(i_lnfree_e), &
     475         6216 :          res(i_eta), dres_dlnRho(i_eta), dres_dlnT(i_eta), &
     476        12432 :          kap_fracs, kap, dlnkap_dlnRho, dlnkap_dlnT, dlnkap_dxa, ierr)
     477              : 
     478         6216 :    end subroutine kap_proc
     479              : 
     480              : end module test_atm_support
        

Generated by: LCOV version 2.0-1