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.6 % 219 205
Test Date: 2026-01-06 18:03:11 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         3109 :    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            1 :       test_verbosely = test_verbosely_in
      44            1 :       cgrav = cgrav_in
      45            1 :       eos_handle = eos_handle_in
      46            1 :       kap_handle = kap_handle_in
      47              : 
      48            1 :       call test_table(ATM_TABLE_TAU_1M1, 'tau=0.1')
      49            1 :       call test_table(ATM_TABLE_TAU_1, 'tau=1')
      50            1 :       call test_table(ATM_TABLE_TAU_10, 'tau=10')
      51            1 :       call test_table(ATM_TABLE_TAU_100, 'tau=100')
      52              : 
      53            1 :       call test_table(ATM_TABLE_WD_TAU_25, 'WD tau=25')
      54            1 :       call test_table(ATM_TABLE_DB_WD_TAU_25, 'DB WD tau=25')
      55            1 :       call test_table(ATM_TABLE_PHOTOSPHERE, 'photosphere')
      56              : 
      57            1 :       call test_T_tau_varying(ATM_T_TAU_EDDINGTON, 'Eddington', -1._dp)
      58            1 :       call test_T_tau_varying(ATM_T_TAU_KRISHNA_SWAMY, 'Krishna-Swamy', -1._dp)
      59            1 :       call test_T_tau_varying(ATM_T_TAU_SOLAR_HOPF, 'solar Hopf', -1._dp)
      60            1 :       call test_T_tau_varying(ATM_T_TAU_TRAMPEDACH_SOLAR, 'Trampedach solar', -1._dp)
      61            1 :       call test_T_tau_varying(ATM_T_TAU_EDDINGTON, 'Eddington', 100._dp)
      62              : 
      63            1 :       call test_T_tau_uniform('fixed', 100._dp)
      64            1 :       call test_T_tau_uniform('iterated', 150._dp)
      65              : 
      66            1 :       call test_irradiated()
      67              : 
      68            1 :    end subroutine do_test_atm
      69              : 
      70              :    !****
      71              : 
      72            7 :    subroutine test_table(table_id, label)
      73              : 
      74              :       integer, intent(in)      :: table_id
      75              :       character(*), intent(in) :: label
      76              : 
      77              :       include 'formats'
      78              : 
      79            7 :       ierr = 0
      80              : 
      81            7 :       if (test_verbosely) then
      82            7 :          write (*, *)
      83            7 :          write (*, *) 'test_table: ', label
      84              :       end if
      85              : 
      86            7 :       if (table_id == ATM_TABLE_WD_TAU_25) then
      87            1 :          logg = 7.1d0
      88            1 :          Teff = 5000
      89            1 :          M = 0.8d0*Msun
      90            1 :          R = sqrt(cgrav*M/exp10(logg))
      91              :          !write(*,*) 'R/Rsun', R/Rsun
      92            1 :          L = pi*crad*clight*R*R*Teff*Teff*Teff*Teff
      93              :          !write(*,*) 'L/Lsun', L/Lsun
      94            6 :       elseif (table_id == ATM_TABLE_DB_WD_TAU_25) then
      95            1 :          logg = 8.0d0
      96            1 :          Teff = 25000
      97            1 :          M = 0.8d0*Msun
      98            1 :          R = sqrt(cgrav*M/exp10(logg))
      99              :          !write(*,*) 'R/Rsun', R/Rsun
     100            1 :          L = pi*crad*clight*R*R*Teff*Teff*Teff*Teff
     101              :          !write(*,*) 'L/Lsun', L/Lsun    else
     102              :       else
     103            5 :          M = Msun
     104            5 :          R = Rsun
     105            5 :          L = Lsun
     106            5 :          Teff = atm_Teff(L, R)
     107              :       end if
     108              : 
     109            7 :       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            7 :          ierr)
     117            7 :       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            7 :       T = exp(lnT)
     123            7 :       P = exp(lnP)
     124              : 
     125            7 :       Prad = radiation_pressure(T)
     126              : 
     127            7 :       if (test_verbosely) write (*, *)
     128            7 :       if (test_verbosely) write (*, '(99a16)') &
     129            7 :          'T', 'log_T', 'log P', 'M/Msun', 'L/Lsun', 'R/Rsun', 'logPgas'
     130            7 :       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            7 :       if (test_verbosely) write (*, *)
     133              : 
     134            7 :    end subroutine test_table
     135              : 
     136              :    !****
     137              : 
     138            5 :    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              :       real(dp) :: errtol
     145              :       integer  :: max_steps
     146              : 
     147              :       include 'formats'
     148              : 
     149            5 :       ierr = 0
     150              : 
     151            5 :       if (tau_base_in < 0._dp) then
     152            4 :          call atm_get_T_tau_base(T_tau_id, tau_base, ierr)
     153            4 :          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            1 :          tau_base = tau_base_in
     159              :       end if
     160              : 
     161            5 :       if (test_verbosely) then
     162            5 :          write (*, *)
     163            5 :          write (*, *) 'test_T_tau_varying: ', label
     164              :       end if
     165              : 
     166              :       ! TEST SOLAR VALUES
     167            5 :       logTeff = log10(5776d0)
     168            5 :       log_gsurf = log10(cgrav*Msun/(Rsun*Rsun))
     169            5 :       log_Rsurf = log10(Rsun)
     170            5 :       log_M = log10(Msun)
     171              : 
     172            5 :       Z = 0.02d0
     173            5 :       X = 0.70d0
     174            5 :       XC = 3.2724592105263235d-03
     175            5 :       XN = 9.5023842105263292d-04
     176            5 :       XO = 8.8218000000000601d-03
     177            5 :       call set_composition()
     178              : 
     179            5 :       R = exp10(log_Rsurf)
     180            5 :       M = exp10(log_M)
     181              : 
     182            5 :       g = exp10(log_gsurf)
     183            5 :       Teff = exp10(logTeff)
     184            5 :       L = pi*crad*clight*R*R*Teff*Teff*Teff*Teff
     185              : 
     186            5 :       errtol = 1.E-9_dp
     187            5 :       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            5 :          ierr)
     197            5 :       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            5 :       T = exp(lnT)
     203            5 :       P = exp(lnP)
     204              : 
     205            5 :       if (test_verbosely) write (*, *)
     206            5 :       if (test_verbosely) write (*, '(99a16)') 'T', 'log T', 'log P', 'M/Msun', 'L/Lsun', 'X', 'Z'
     207            5 :       if (test_verbosely) write (*, '(i16,99f16.8)') &
     208            5 :          floor(0.5d0 + T), log10(T), log10(P), M/Msun, L/Lsun, X, Z
     209            5 :       if (test_verbosely) write (*, *)
     210              : 
     211            5 :       deallocate (chem_id, net_iso)
     212              : 
     213              :    end subroutine test_T_tau_varying
     214              : 
     215              :    !****
     216              : 
     217            2 :    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              :       real(dp) :: tau_base
     223              :       real(dp) :: errtol
     224              : 
     225              :       include 'formats'
     226              : 
     227            2 :       if (test_verbosely) then
     228            2 :          write (*, *)
     229            2 :          write (*, *) 'test_T_tau_uniform: ', TRIM(T_tau_opacity)
     230              :       end if
     231              : 
     232            2 :       tau_base = tau_base_in
     233            2 :       if (tau_base <= 0._dp) then
     234            0 :          tau_base = 2._dp/3._dp
     235              :       end if
     236              : 
     237            2 :       Pextra_factor = 1._dp
     238              : 
     239            1 :       select case (T_tau_opacity)
     240              : 
     241              :       case ('fixed')
     242              : 
     243            1 :          M = 1.9892000000000002D+32
     244            1 :          R = 6.3556231577545586D+10
     245            1 :          L = 2.4015399190199118D+32
     246            1 :          Teff = atm_Teff(L, R)
     247              : 
     248            1 :          kap_guess = 5.8850802481174469D-02
     249              : 
     250            1 :          max_iters = 0
     251              : 
     252              :       case ('iterated')
     253              : 
     254            1 :          logTeff = log10(5776._dp)
     255            1 :          log_gsurf = log10(cgrav*Msun/(Rsun*Rsun))
     256            1 :          log_Rsurf = log10(Rsun)
     257            1 :          log_M = log10(Msun)
     258              : 
     259            1 :          R = exp10(log_Rsurf)
     260            1 :          M = exp10(log_M)
     261            1 :          Teff = exp10(logTeff)
     262            1 :          L = pi*crad*clight*R*R*Teff*Teff*Teff*Teff
     263              : 
     264            1 :          kap_guess = 0.5d0
     265              : 
     266            1 :          max_iters = 30
     267              : 
     268              :       case default
     269              : 
     270            0 :          write (*, *) 'unknown value for T_tau_opacity '//trim(T_tau_opacity)
     271              : 
     272            2 :          stop
     273              : 
     274              :       end select
     275              : 
     276            2 :       Z = 0.02d0
     277            2 :       X = 0.70d0
     278            2 :       XC = 3.2724592105263235d-03
     279            2 :       XN = 9.5023842105263292d-04
     280            2 :       XO = 8.8218000000000601d-03
     281            2 :       call set_composition()
     282              : 
     283            2 :       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            2 :          ierr)
     292            2 :       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            2 :       if (test_verbosely) write (*, 1) 'atm_get_grey logP surf', lnP/ln10
     297            2 :       if (test_verbosely) write (*, 1) 'atm_get_grey logT surf', lnT/ln10
     298            2 :       if (test_verbosely) write (*, 1) 'atm_get_grey tau_phot', tau_base
     299            2 :       if (test_verbosely) write (*, *)
     300              : 
     301            2 :       deallocate (chem_id, net_iso)
     302              : 
     303            2 :    end subroutine test_T_tau_uniform
     304              : 
     305              :    !****
     306              : 
     307            3 :    subroutine test_irradiated()
     308              : 
     309              :       real(dp) :: errtol
     310              :       type(Kap_General_Info), pointer :: rq
     311              : 
     312              :       include 'formats'
     313              : 
     314            1 :       if (test_verbosely) then
     315            1 :          write (*, *)
     316            1 :          write (*, *) 'test_irradiated'
     317              :       end if
     318              : 
     319            1 :       ierr = 0
     320              : 
     321            1 :       X = 0.70d0
     322            1 :       Z = 1d-2
     323            1 :       XC = 3.2724592105263235d-03
     324            1 :       XN = 9.5023842105263292d-04
     325            1 :       XO = 8.8218000000000601d-03
     326              : 
     327            1 :       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            1 :       call kap_ptr(kap_handle, rq, ierr)
     332            1 :       if (ierr /= 0) return
     333            1 :       rq%kap_lowT_option = kap_lowT_Freedman11
     334              : 
     335              :       ! must set up tables again after changing options
     336            1 :       call kap_setup_tables(kap_handle, ierr)
     337              : 
     338            1 :       errtol = 1.E-6_dp
     339            1 :       max_iters = 30
     340              : 
     341            1 :       T_eq = 1000.
     342            1 :       kap_v = 4.E-3_dp
     343            1 :       kap_guess = 1.5d-2
     344            1 :       gamma = 0._dp
     345            1 :       P = 1d6
     346            1 :       M = 1.5d0*M_jupiter
     347              :       tau = 10  ! just a guess for use in getting R
     348            1 :       R = sqrt(cgrav*M*tau/(P*kap_guess))  ! g = P*kap/tau = G*M/R^2
     349            1 :       T_int = 900
     350            1 :       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            1 :          ierr)
     358            1 :       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            1 :       if (test_verbosely) write (*, *)
     364            1 :       if (test_verbosely) write (*, 1) 'test_grey_irradiated: kap', kap
     365            1 :       if (test_verbosely) write (*, 1) 'M/M_jupiter', M/M_jupiter
     366            1 :       if (test_verbosely) write (*, 1) 'R/R_jupiter', R/R_jupiter
     367            1 :       if (test_verbosely) write (*, 1) 'R/Rsun', R/Rsun
     368            1 :       if (test_verbosely) write (*, 1) 'kap_v', kap_v
     369            1 :       if (test_verbosely) write (*, 1) 'P', P
     370            1 :       if (test_verbosely) write (*, *)
     371              : 
     372            1 :       if (test_verbosely) write (*, 1) 'tau', tau
     373            1 :       if (test_verbosely) write (*, 1) 'Teff', Teff
     374            1 :       if (test_verbosely) write (*, 1) 'T_eq', T_eq
     375            1 :       if (test_verbosely) write (*, 1) 'T_int', T_int
     376            1 :       if (test_verbosely) write (*, 1) 'T', exp(lnT)
     377            1 :       if (test_verbosely) write (*, 1) 'logT', lnT/ln10
     378            1 :       if (test_verbosely) write (*, *)
     379              : 
     380            1 :       deallocate (chem_id, net_iso)
     381              : 
     382              :    end subroutine test_irradiated
     383              : 
     384              :    !****
     385              : 
     386            8 :    subroutine set_composition()
     387              :       real(dp) :: xz, z2bar, ye, mass_correction, sumx, &
     388              :                   dabar_dx(species), dzbar_dx(species), dmc_dx(species)
     389              :       integer :: i
     390              :       type(Kap_General_Info), pointer :: rq
     391            8 :       call kap_ptr(kap_handle, rq, ierr)
     392            8 :       rq%Zbase = Z
     393            8 :       Y = 1 - (X + Z)
     394            8 :       allocate (chem_id(species), net_iso(num_chem_isos), stat=ierr)
     395            8 :       if (ierr /= 0) then
     396            0 :          write (*, *) 'allocate failed'
     397            0 :          call mesa_error(__FILE__, __LINE__)
     398              :       end if
     399           64 :       chem_id(:) = [ih1, ihe4, ic12, in14, io16, ine20, img24]
     400        62856 :       net_iso(:) = 0
     401           64 :       forall (i=1:species) net_iso(chem_id(i)) = i
     402           64 :       xa(:) = [X, Y, xc, xn, xo, 0d0, 0d0]
     403           64 :       xa(species) = 1 - sum(xa(:))
     404              :       call composition_info( &
     405              :          species, chem_id, xa, X, Y, xz, abar, zbar, z2bar, z53bar, ye, &
     406            8 :          mass_correction, sumx, dabar_dx, dzbar_dx, dmc_dx)
     407            8 :    end subroutine set_composition
     408              : 
     409              :    !****
     410              : 
     411         3108 :    subroutine eos_proc( &
     412              :       lnP, lnT, &
     413         3108 :       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              :       real(dp) :: T, P, Prad, Pgas, logPgas, rho
     428              :       real(dp) :: logRho, dlnRho_dlnPgas, dlnRho_dlnT
     429              :       real(dp), dimension(num_eos_d_dxa_results, species) :: dres_dxa
     430              : 
     431         3108 :       T = exp(lnT)
     432         3108 :       P = exp(lnP)
     433              : 
     434         3108 :       Prad = radiation_pressure(T)
     435         3108 :       Pgas = max(1E-99_dp, P - Prad)
     436         3108 :       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         3108 :          res, dres_dlnRho, dres_dlnT, dres_dxa, ierr)
     444              : 
     445         3108 :       lnRho = logRho*ln10
     446              : 
     447         3108 :    end subroutine eos_proc
     448              : 
     449              :    !****
     450              : 
     451         3108 :    subroutine kap_proc( &
     452         3108 :       lnRho, lnT, res, dres_dlnRho, dres_dlnT, &
     453              :       kap, dlnkap_dlnRho, dlnkap_dlnT, &
     454              :       ierr)
     455              : 
     456         3108 :       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              :       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         3108 :          lnRho/ln10, lnT/ln10, res(i_lnfree_e), dres_dlnRho(i_lnfree_e), dres_dlnT(i_lnfree_e), &
     475         3108 :          res(i_eta), dres_dlnRho(i_eta), dres_dlnT(i_eta), &
     476         6216 :          kap_fracs, kap, dlnkap_dlnRho, dlnkap_dlnT, dlnkap_dxa, ierr)
     477              : 
     478         3108 :    end subroutine kap_proc
     479              : 
     480              : end module test_atm_support
        

Generated by: LCOV version 2.0-1