LCOV - code coverage report
Current view: top level - atm/private - atm_table.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 23.7 % 194 46
Test Date: 2025-05-08 18:23:42 Functions: 33.3 % 3 1

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2019  The MESA Team
       4              : !
       5              : !   This program is free software: you can redistribute it and/or modify
       6              : !   it under the terms of the GNU Lesser General Public License
       7              : !   as published by the Free Software Foundation,
       8              : !   either version 3 of the License, or (at your option) any later version.
       9              : !
      10              : !   This program is distributed in the hope that it will be useful,
      11              : !   but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              : !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13              : !   See the GNU Lesser General Public License for more details.
      14              : !
      15              : !   You should have received a copy of the GNU Lesser General Public License
      16              : !   along with this program. If not, see <https://www.gnu.org/licenses/>.
      17              : !
      18              : ! ***********************************************************************
      19              : 
      20              : module atm_table
      21              : 
      22              :   use const_def, only: dp, ln10
      23              :   use math_lib
      24              :   use utils_lib, only: mesa_error
      25              : 
      26              :   implicit none
      27              : 
      28              :   private
      29              :   public :: eval_table
      30              :   public :: get_table_alfa_beta
      31              :   public :: get_table_base
      32              : 
      33              : contains
      34              : 
      35           14 :   subroutine eval_table( &
      36              :        L, R, M, cgrav, id, Z, skip_partials, &
      37              :        Teff, &
      38              :        lnT, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
      39              :        lnP, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap, &
      40              :        ierr)
      41              : 
      42              :     use atm_def
      43              :     use eos_lib, only: radiation_pressure
      44              :     use table_atm, only: get_table_values
      45              :     use utils_lib, only: is_bad
      46              : 
      47              :     real(dp), intent(in)  :: L
      48              :     real(dp), intent(in)  :: R
      49              :     real(dp), intent(in)  :: M
      50              :     real(dp), intent(in)  :: cgrav
      51              :     integer, intent(in)   :: id
      52              :     real(dp), intent(in)  :: Z
      53              :     logical, intent(in)   :: skip_partials
      54              :     real(dp), intent(in)  :: Teff
      55              :     real(dp), intent(out) :: lnT
      56              :     real(dp), intent(out) :: dlnT_dL
      57              :     real(dp), intent(out) :: dlnT_dlnR
      58              :     real(dp), intent(out) :: dlnT_dlnM
      59              :     real(dp), intent(out) :: dlnT_dlnkap
      60              :     real(dp), intent(out) :: lnP
      61              :     real(dp), intent(out) :: dlnP_dL
      62              :     real(dp), intent(out) :: dlnP_dlnR
      63              :     real(dp), intent(out) :: dlnP_dlnM
      64              :     real(dp), intent(out) :: dlnP_dlnkap
      65              :     integer, intent(out)  :: ierr
      66              : 
      67              :     logical, parameter :: dbg = .false.
      68              : 
      69              :     real(dp) :: g
      70           14 :     real(dp) :: logg
      71           14 :     real(dp) :: Pgas
      72           14 :     real(dp) :: dPgas_dTeff
      73           14 :     real(dp) :: dPgas_dlogg
      74           14 :     real(dp) :: T
      75           14 :     real(dp) :: dT_dTeff
      76           14 :     real(dp) :: dT_dlogg
      77           14 :     real(dp) :: Prad
      78           14 :     real(dp) :: P
      79           14 :     real(dp) :: dlnTeff_dL
      80           14 :     real(dp) :: dlnTeff_dlnR
      81           14 :     real(dp) :: dTeff_dlnR
      82           14 :     real(dp) :: dlogg_dlnR
      83           14 :     real(dp) :: dlogg_dlnM
      84           14 :     real(dp) :: dPgas_dlnR
      85           14 :     real(dp) :: dPgas_dlnM
      86           14 :     real(dp) :: dPgas_dlnTeff
      87           14 :     real(dp) :: dPrad_dlnTeff
      88           14 :     real(dp) :: dPrad_dlnR
      89           14 :     real(dp) :: dPrad_dL
      90           14 :     real(dp) :: dT_dlnR
      91           14 :     real(dp) :: dT_dlnM
      92           14 :     real(dp) :: dT_dlnTeff
      93              : 
      94              :     include 'formats'
      95              : 
      96           14 :     ierr = 0
      97              : 
      98              :     ! Sanity checks
      99              : 
     100           14 :     if (L <= 0._dp .OR. R <= 0._dp .OR. M <= 0._dp) then
     101            0 :        ierr = -1
     102            0 :        return
     103              :     end if
     104              : 
     105              :     ! Evaluate the gravity
     106              : 
     107           14 :     g = cgrav*M/(R*R)
     108           14 :     logg = log10(g)
     109              : 
     110              :     ! Perform the table lookup
     111              : 
     112              :     if (dbg) write(*,*) 'call get_table_values', id
     113              :     call get_table_values( &
     114              :          id, Z, logg, Teff, &
     115              :          Pgas, dPgas_dTeff, dPgas_dlogg, &
     116              :          T, dT_dTeff, dT_dlogg, &
     117           14 :          ierr)
     118           14 :     if (ierr /= 0) then
     119              :        if (dbg) write(*,*) 'get_table_values(_at_fixed_Z) ierr', ierr
     120              :        return
     121              :     end if
     122              : 
     123              :     ! Set up lnT and lnP
     124              : 
     125           14 :     lnT = log(T)
     126              : 
     127           14 :     Prad = radiation_pressure(T)
     128           14 :     P = Pgas + Prad
     129           14 :     lnP = log(P)
     130              : 
     131              :     ! Set up partials
     132              : 
     133           14 :     if (.NOT. skip_partials) then
     134              : 
     135            0 :        dlnTeff_dlnR = -0.5_dp
     136            0 :        dlnTeff_dL = 0.25_dp/L
     137            0 :        dTeff_dlnR = Teff*dlnTeff_dlnR
     138              : 
     139            0 :        dlogg_dlnR = -2._dp/ln10
     140            0 :        dlogg_dlnM = 1._dp/ln10
     141              : 
     142            0 :        dPgas_dlnR = dPgas_dlogg*dlogg_dlnR + dPgas_dTeff*dTeff_dlnR
     143            0 :        dPgas_dlnM = dPgas_dlogg*dlogg_dlnM
     144            0 :        dPgas_dlnTeff = dPgas_dTeff*Teff
     145              : 
     146            0 :        dPrad_dlnTeff = 4._dp*Prad*dT_dTeff*Teff/T
     147            0 :        dPrad_dlnR = dPrad_dlnTeff*dlnTeff_dlnR
     148            0 :        dPrad_dL = dPrad_dlnTeff*dlnTeff_dL
     149              : 
     150            0 :        dlnP_dL = (dPgas_dlnTeff + dPrad_dlnTeff)*dlnTeff_dL / P
     151            0 :        dlnP_dlnR = (dPgas_dlnR + dPrad_dlnTeff*dlnTeff_dlnR) / P
     152            0 :        dlnP_dlnM = dPgas_dlnM/P
     153            0 :        dlnP_dlnkap = 0._dp
     154              : 
     155            0 :        dT_dlnTeff = dT_dTeff*Teff
     156            0 :        dT_dlnR = dT_dlogg*dlogg_dlnR + dT_dlnTeff*dlnTeff_dlnR
     157            0 :        dT_dlnM = dT_dlogg*dlogg_dlnM
     158              : 
     159            0 :        dlnT_dL = dT_dlnTeff*dlnTeff_dL / T
     160            0 :        dlnT_dlnR = dT_dlnR / T
     161            0 :        dlnT_dlnM = dT_dlnM / T
     162            0 :        dlnT_dlnkap = 0._dp
     163              : 
     164              :     else
     165              : 
     166           14 :        dlnP_dL = 0._dp
     167           14 :        dlnP_dlnR = 0._dp
     168           14 :        dlnP_dlnM = 0._dp
     169           14 :        dlnP_dlnkap = 0._dp
     170              : 
     171           14 :        dlnT_dL = 0._dp
     172           14 :        dlnT_dlnR = 0._dp
     173           14 :        dlnT_dlnM = 0._dp
     174           14 :        dlnT_dlnkap = 0._dp
     175              : 
     176              :     end if
     177              : 
     178           14 :     if (dbg .or. is_bad(lnP) .or. is_bad(lnT)) then
     179            0 :        write(*,*) 'eval_table'
     180            0 :        write(*,1) 'Teff', Teff
     181            0 :        write(*,1) 'T', T
     182            0 :        write(*,1) 'dT_dTeff', dT_dTeff
     183            0 :        write(*,1) 'dT_dlogg', dT_dlogg
     184            0 :        write(*,'(A)')
     185            0 :        ierr = -1
     186            0 :        return
     187              :        !if (is_bad(lnP) .or. is_bad(lnT)) call mesa_error(__FILE__,__LINE__,'eval_table')
     188              :     end if
     189              : 
     190              :     return
     191              : 
     192           14 :   end subroutine eval_table
     193              : 
     194              : 
     195            0 :   subroutine get_table_alfa_beta( &
     196              :        L, Teff, R, M, cgrav, id, alfa, beta, ierr)
     197              : 
     198           14 :     use atm_def
     199              :     use table_atm, only: &
     200              :          ai_two_thirds, ai_100, ai_10, ai_1, ai_1m1, ai_wd_25, ai_db_wd_25
     201              : 
     202              :     real(dp), intent(in)  :: L
     203              :     real(dp), intent(in)  :: Teff
     204              :     real(dp), intent(in)  :: R
     205              :     real(dp), intent(in)  :: M
     206              :     real(dp), intent(in)  :: cgrav
     207              :     integer, intent(in)   :: id
     208              :     real(dp), intent(out) :: alfa
     209              :     real(dp), intent(out) :: beta
     210              :     integer, intent(out)  :: ierr
     211              : 
     212              :     integer, parameter :: PURE_GREY = 1
     213              :     integer, parameter :: PURE_TABLE = 2
     214              :     integer, parameter :: BLEND_IN_X = 3
     215              :     integer, parameter :: BLEND_IN_Y = 4
     216              :     integer, parameter :: BLEND_CORNER_OUT = 5
     217              : 
     218              :     logical, parameter :: dbg = .false.
     219              : 
     220            0 :     real(dp)                :: g
     221            0 :     real(dp)                :: logTeff
     222            0 :     real(dp)                :: logg
     223              :     type(Atm_Info), pointer :: ai
     224            0 :     real(dp)                :: logg_max
     225            0 :     real(dp)                :: logg_min
     226            0 :     real(dp)                :: logTeff_max
     227            0 :     real(dp)                :: logTeff_min
     228            0 :     real(dp)                :: Teff_max
     229            0 :     real(dp)                :: Teff_min
     230            0 :     real(dp)                :: logg_min_margin
     231            0 :     real(dp)                :: logg_max_margin
     232            0 :     real(dp)                :: logTeff_min_margin
     233            0 :     real(dp)                :: logTeff_max_margin
     234            0 :     real(dp)                :: logg1
     235            0 :     real(dp)                :: logg2
     236            0 :     real(dp)                :: logg3
     237            0 :     real(dp)                :: logg4
     238            0 :     real(dp)                :: logTeff1
     239            0 :     real(dp)                :: logTeff2
     240            0 :     real(dp)                :: logTeff3
     241            0 :     real(dp)                :: logTeff4
     242            0 :     real(dp)                :: c_dx
     243            0 :     real(dp)                :: c_dy
     244              :     integer                 :: iregion
     245              :     integer                 :: logg_index
     246              :     integer                 :: ng
     247              :     integer                 :: j
     248              : 
     249              :     include 'formats'
     250              : 
     251            0 :     ierr = 0
     252              : 
     253              :     ! Sanity checks
     254              : 
     255            0 :     if (L <= 0._dp .OR. R <= 0._dp .OR. M <= 0._dp) then
     256            0 :        ierr = -1
     257            0 :        return
     258              :     end if
     259              : 
     260              :     ! Evaluate the gravity
     261              : 
     262            0 :     g = cgrav*M/(R*R)
     263            0 :     logTeff = log10(Teff)
     264            0 :     logg = log10(g)
     265              : 
     266              :     ! Set up the table pointer
     267              : 
     268            0 :     select case (id)
     269              :     case (ATM_TABLE_PHOTOSPHERE)
     270              :        ai => ai_two_thirds
     271              :     case (ATM_TABLE_TAU_100)
     272              :        ai => ai_100
     273              :     case (ATM_TABLE_TAU_10)
     274              :        ai => ai_10
     275              :     case (ATM_TABLE_TAU_1)
     276              :        ai => ai_1
     277              :     case (ATM_TABLE_TAU_1M1)
     278              :        ai => ai_1m1
     279              :     case (ATM_TABLE_WD_TAU_25)
     280              :        ai => ai_wd_25
     281              :     case (ATM_TABLE_DB_WD_TAU_25)
     282            0 :        ai => ai_db_wd_25
     283              :     case default
     284            0 :        write(*,*) 'Invalid id in get_table_alfa_beta:', id
     285            0 :        call mesa_error(__FILE__,__LINE__)
     286              :     end select
     287              : 
     288            0 :     ng = ai% ng
     289            0 :     logg_max = ai% logg_array(ng)
     290            0 :     logg_min = ai% logg_array(1)
     291              : 
     292              :     ! First, locate current point logg array for use with Teff_bound
     293              : 
     294            0 :     if (logg <= logg_min) then
     295              :        logg_index = 1
     296            0 :     else if (logg >= logg_max) then
     297              :        logg_index = ng
     298              :     else
     299              :        logg_index = ng
     300            0 :        do j = 1, ng-1
     301            0 :           if (ai% logg_array(j) <= logg) then
     302            0 :              logg_index = j
     303              :           end if
     304              :        end do
     305              :     end if
     306              : 
     307            0 :     Teff_max = ai% Teff_bound(logg_index)
     308            0 :     Teff_min = ai% Teff_array(1)
     309            0 :     logTeff_max = log10(Teff_max)
     310            0 :     logTeff_min = log10(Teff_min)
     311              : 
     312              :     ! Set up margins for blending
     313              : 
     314            0 :     logg_max_margin = 0.01d0
     315            0 :     logg_min_margin = 0.5d0
     316            0 :     logTeff_max_margin = 0.01d0
     317            0 :     logTeff_min_margin = 0.01d0
     318              : 
     319              :     ! if (id == ATM_TABLE_WD_TAU_25) then
     320              :     !    logg_max_margin = 0.5d0
     321              :     !    logg_min_margin = 0.5d0
     322              :     !    logTeff_max_margin = 0.2d0
     323              :     !    logTeff_min_margin = 1d0
     324              :     !    logg1 = logg_max + logg_max_margin
     325              :     !    logg2 = logg_max
     326              :     !    logg3 = logg_min
     327              :     !    logg4 = logg_min - logg_min_margin
     328              :     !    logTeff1 = logTeff_max + logTeff_max_margin
     329              :     !    logTeff2 = logTeff_max
     330              :     !    logTeff3 = logTeff_min
     331              :     !    logTeff4 = logTeff_min - logTeff_min_margin
     332              :     ! else
     333            0 :        logg1 = logg_max
     334            0 :        logg2 = logg_max - logg_max_margin
     335            0 :        logg3 = logg_min + logg_min_margin
     336            0 :        logg4 = logg_min
     337            0 :        logTeff1 = logTeff_max
     338            0 :        logTeff2 = logTeff_max - logTeff_max_margin
     339            0 :        logTeff3 = logTeff_min
     340            0 :        logTeff4 = logTeff_min
     341              :     ! end if
     342              : 
     343              :     ! Decide on what sort of region we're in
     344              : 
     345            0 :     if (logg < logg4 .or. logg > logg1 .or. logTeff > logTeff1) then
     346            0 :        iregion = pure_grey
     347            0 :     else if (logTeff > logTeff2) then
     348            0 :        c_dy = (logTeff - logTeff2) / (logTeff1 - logTeff2)
     349            0 :        if (logg > logg2) then
     350            0 :           c_dx = (logg - logg2) / (logg1 - logg2)
     351            0 :           iregion = blend_corner_out
     352            0 :        else if (logg > logg3) then
     353            0 :           iregion = blend_in_y
     354              :        else  ! logg > logg4
     355            0 :           c_dx = (logg - logg3) / (logg4 - logg3)
     356            0 :           iregion = blend_corner_out
     357              :        end if
     358            0 :     else if (logTeff >= logTeff3) then
     359            0 :        if (logg > logg2) then
     360            0 :           c_dx = (logg - logg2) / (logg1 - logg2)
     361            0 :           iregion = blend_in_x
     362            0 :        else if (logg > logg3) then
     363            0 :           iregion = pure_table
     364              :        else  ! logg > logg4
     365            0 :           c_dx = (logg - logg3) / (logg4 - logg3)
     366            0 :           iregion = blend_in_x
     367              :        end if
     368            0 :     else if (logTeff > logTeff4) then
     369            0 :        c_dy = (logTeff - logTeff3) / (logTeff4 - logTeff3)
     370            0 :        if (logg > logg2) then
     371            0 :           c_dx = (logg - logg2) / (logg1 - logg2)
     372            0 :           iregion = blend_corner_out
     373            0 :        else if (logg > logg3) then
     374            0 :           iregion = blend_in_y
     375              :        else  ! logg > logg4
     376            0 :           c_dx = (logg - logg3) / (logg4 - logg3)
     377            0 :           iregion = blend_corner_out
     378              :        end if
     379              :     else  ! logTeff <= logTeff4
     380            0 :        iregion = pure_grey
     381              :     end if
     382              : 
     383              :     ! Set up alfa and beta
     384              : 
     385            0 :     select case (iregion)
     386              :     case (pure_grey)
     387            0 :        alfa = 1._dp
     388            0 :        beta = 0._dp
     389              :     case (pure_table)
     390            0 :        alfa = 0._dp
     391            0 :        beta = 1._dp
     392              :     case (blend_in_y)
     393            0 :        alfa = c_dy
     394            0 :        beta = 1._dp - alfa
     395              :     case (blend_in_x)
     396            0 :        alfa = c_dx
     397            0 :        beta = 1._dp - alfa
     398              :     case (blend_corner_out)
     399            0 :        alfa = min(1d0, sqrt(c_dx*c_dx + c_dy*c_dy))
     400            0 :        beta = 1 - alfa
     401              :     case default
     402            0 :        write(*,*) 'Invalid iregion in get_table_alfa_beta:', iregion
     403            0 :        call mesa_error(__FILE__,__LINE__)
     404              :     end select
     405              : 
     406              :     return
     407              : 
     408            0 :   end subroutine get_table_alfa_beta
     409              : 
     410              : 
     411            0 :   subroutine get_table_base (id, tau_base, ierr)
     412              : 
     413            0 :     use atm_def
     414              : 
     415              :     integer, intent(in)   :: id
     416              :     real(dp), intent(out) :: tau_base
     417              :     integer, intent(out)  :: ierr
     418              : 
     419            0 :     ierr = 0
     420              : 
     421              :     ! Get the base optical depth for the atmosphere
     422              : 
     423            0 :     select case (id)
     424              :     case (ATM_TABLE_PHOTOSPHERE)
     425            0 :        tau_base = 2._dp/3._dp
     426              :     case (ATM_TABLE_TAU_100)
     427            0 :        tau_base = 100._dp
     428              :     case (ATM_TABLE_TAU_10)
     429            0 :        tau_base = 10._dp
     430              :     case (ATM_TABLE_TAU_1)
     431            0 :        tau_base = 1._dp
     432              :     case (ATM_TABLE_TAU_1M1)
     433            0 :        tau_base = 0.1_dp
     434              :     case (ATM_TABLE_WD_TAU_25)
     435            0 :        tau_base = 25.1188_dp
     436              :     case (ATM_TABLE_DB_WD_TAU_25)
     437            0 :        tau_base = 25._dp
     438              :     case default
     439            0 :        write(*,*) 'Invalid id in get_table_base:', id
     440            0 :        call mesa_error(__FILE__,__LINE__)
     441              :     end select
     442              : 
     443            0 :     return
     444              : 
     445              :   end subroutine get_table_base
     446              : 
     447              : end module atm_table
        

Generated by: LCOV version 2.0-1