LCOV - code coverage report
Current view: top level - star/private - eos_support.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 20.5 % 83 17
Test Date: 2025-05-08 18:23:42 Functions: 25.0 % 8 2

            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 eos_support
      21              : 
      22              :   use const_def, only: dp, ln10, arg_not_provided
      23              :   use star_private_def
      24              :   use utils_lib, only : is_bad, mesa_error
      25              : 
      26              :   implicit none
      27              : 
      28              :   private
      29              :   public :: get_eos
      30              :   public :: solve_eos_given_DE
      31              :   public :: solve_eos_given_DEgas
      32              :   public :: solve_eos_given_DP
      33              :   public :: solve_eos_given_DS
      34              :   public :: solve_eos_given_PT
      35              :   public :: solve_eos_given_PgasT
      36              :   public :: solve_eos_given_PgasT_auto
      37              : 
      38              :   integer, parameter :: MAX_ITER_FOR_SOLVE = 100
      39              : 
      40              : contains
      41              : 
      42              :   ! Get eos results data given density & temperature
      43              : 
      44       192472 :   subroutine get_eos( &
      45       192472 :        s, k, xa, &
      46              :        Rho, logRho, T, logT, &
      47              :        res, dres_dlnRho, dres_dlnT, &
      48       192472 :        dres_dxa, ierr)
      49              : 
      50              :     use eos_lib, only: eosDT_get
      51              :     use eos_def, only: num_eos_basic_results, num_eos_d_dxa_results, num_helm_results, i_lnE
      52              : 
      53              :     type (star_info), pointer :: s
      54              :     integer, intent(in) :: k  ! 0 means not being called for a particular cell
      55              :     real(dp), intent(in) :: xa(:), Rho, logRho, T, logT
      56              :     real(dp), dimension(num_eos_basic_results), intent(out) :: &
      57              :          res, dres_dlnRho, dres_dlnT
      58              :     real(dp), intent(out) :: dres_dxa(num_eos_d_dxa_results,s% species)
      59              :     integer, intent(out) :: ierr
      60              : 
      61              :     integer :: j
      62              : 
      63              :     include 'formats'
      64              : 
      65       192472 :     ierr = 0
      66              : 
      67       192472 :     if (s% doing_timing) &
      68            0 :        s% timing_num_get_eos_calls = s% timing_num_get_eos_calls + 1
      69              : 
      70       192472 :     if(logRho < -25) then
      71              :       ! Provide some hard lower limit on what we would even try to evalue the eos at
      72              :       ! Going to low causes FPE's when we try to evaluate certain derivatives that need (rho**power)
      73            0 :       s% retry_message = 'eos evaluated at too low a density'
      74            0 :       ierr = -1
      75            0 :       return
      76              :     end if
      77              : 
      78              :     call eosDT_get( &
      79              :        s% eos_handle, s% species, s% chem_id, s% net_iso, xa, &
      80              :        Rho, logRho, T, logT, &
      81       192472 :        res, dres_dlnRho, dres_dlnT, dres_dxa, ierr)
      82              : 
      83       192472 :     if (ierr /= 0) then
      84            0 :        s% retry_message = 'get_eos failed'
      85            0 :        if (s% report_ierr) then
      86            0 :           !$OMP critical (get_eos_critical)
      87            0 :           write(*,*) 'get_eos ierr', ierr
      88            0 :           write(*,2) 'k', k
      89            0 :           do j=1,s% species
      90            0 :              write(*,2) 'xa(j) ' // trim(s% nameofequ(j+s% nvar_hydro)), j, xa(j)
      91              :           end do
      92            0 :           write(*,1) 'log10Rho', logRho
      93            0 :           write(*,1) 'log10T', logT
      94            0 :           if (s% stop_for_bad_nums .and. &
      95            0 :                is_bad(logRho+logT)) call mesa_error(__FILE__,__LINE__,'do_eos_for_cell')
      96              :           !$OMP end critical (get_eos_critical)
      97              :        end if
      98            0 :        return
      99              :     end if
     100              : 
     101       192472 :   end subroutine get_eos
     102              : 
     103              : 
     104              :   ! Solve for temperature & eos results data given density & energy
     105              : 
     106         1472 :   subroutine solve_eos_given_DE( &
     107         1472 :        s, k, xa, &
     108              :        logRho, logE, logT_guess, logT_tol, logE_tol, &
     109         1472 :        logT, res, dres_dlnRho, dres_dlnT, dres_dxa, &
     110              :        ierr)
     111              : 
     112       192472 :     use eos_def
     113              :     use eos_lib, only: eosDT_get_T
     114              : 
     115              :     type (star_info), pointer :: s
     116              :     integer, intent(in) :: k  ! 0 indicates not for a particular cell.
     117              :     real(dp), intent(in) :: &
     118              :          xa(:), logRho, logE, &
     119              :          logT_guess, logT_tol, logE_tol
     120              :     real(dp), intent(out) :: logT
     121              :     real(dp), dimension(num_eos_basic_results), intent(out) :: &
     122              :          res, dres_dlnRho, dres_dlnT
     123              :     real(dp), intent(out) :: dres_dxa(num_eos_d_dxa_results,s% species)
     124              :     integer, intent(out) :: ierr
     125              : 
     126              :     integer :: eos_calls
     127              : 
     128              :     include 'formats'
     129              : 
     130              :     ierr = 0
     131              : 
     132              :     call eosDT_get_T( &
     133              :        s% eos_handle, &
     134              :        s% species, s% chem_id, s% net_iso, xa, &
     135              :        logRho, i_lnE, logE*ln10, &
     136              :        logT_tol, logE_tol*ln10, MAX_ITER_FOR_SOLVE, logT_guess,  &
     137              :        arg_not_provided, arg_not_provided, arg_not_provided, arg_not_provided, &
     138              :        logT, res, dres_dlnRho, dres_dlnT, dres_dxa, &
     139         1472 :        eos_calls, ierr)
     140              : 
     141         1472 :     if (s% doing_timing) s% timing_num_solve_eos_calls = s% timing_num_solve_eos_calls + eos_calls
     142              : 
     143         1472 :   end subroutine solve_eos_given_DE
     144              : 
     145              : 
     146              :   ! Solve for temperature & eos results data given density & gas energy
     147              : 
     148            0 :   subroutine solve_eos_given_DEgas( &
     149            0 :        s, k, xa, &
     150              :        logRho, egas, logT_guess, logT_tol, egas_tol, &
     151            0 :        logT, res, dres_dlnRho, dres_dlnT, dres_dxa, &
     152              :        ierr)
     153              : 
     154         1472 :     use eos_def
     155              :     use eos_lib, only: eosDT_get_T
     156              : 
     157              :     type (star_info), pointer :: s
     158              :     integer, intent(in) :: k  ! 0 indicates not for a particular cell.
     159              :     real(dp), intent(in) :: &
     160              :          xa(:), logRho, egas, &
     161              :          logT_guess, logT_tol, egas_tol
     162              :     real(dp), intent(out) :: logT
     163              :     real(dp), dimension(num_eos_basic_results), intent(out) :: &
     164              :          res, dres_dlnRho, dres_dlnT
     165              :     real(dp), intent(out) :: dres_dxa(num_eos_d_dxa_results,s% species)
     166              :     integer, intent(out) :: ierr
     167              : 
     168              :     integer :: eos_calls
     169              : 
     170              :     include 'formats'
     171              : 
     172              :     ierr = 0
     173              : 
     174            0 :     if (s% doing_timing) s% timing_num_solve_eos_calls = s% timing_num_solve_eos_calls + 1
     175              : 
     176              :     call eosDT_get_T( &
     177              :        s% eos_handle, &
     178              :        s% species, s% chem_id, s% net_iso, xa, &
     179              :        logRho, i_egas, egas, logT_tol, egas_tol, MAX_ITER_FOR_SOLVE, logT_guess, &
     180              :        arg_not_provided, arg_not_provided, arg_not_provided, arg_not_provided, &
     181              :        logT, res, dres_dlnRho, dres_dlnT, &
     182            0 :        dres_dxa, eos_calls, ierr)
     183              : 
     184            0 :   end subroutine solve_eos_given_DEgas
     185              : 
     186              : 
     187              :   ! Solve for temperature & eos results data given density & pressure
     188              : 
     189            0 :   subroutine solve_eos_given_DP( &
     190            0 :        s, k, xa, &
     191              :        logRho, logP, logT_guess, logT_tol, logP_tol, &
     192            0 :        logT, res, dres_dlnRho, dres_dlnT, dres_dxa, &
     193              :        ierr)
     194              : 
     195            0 :     use eos_def
     196              :     use eos_lib, only: eosDT_get_T
     197              : 
     198              :     type (star_info), pointer :: s
     199              :     integer, intent(in) :: k  ! 0 indicates not for a particular cell.
     200              :     real(dp), intent(in) :: &
     201              :          xa(:), logRho, logP, &
     202              :          logT_guess, logT_tol, logP_tol
     203              :     real(dp), intent(out) :: logT
     204              :     real(dp), dimension(num_eos_basic_results), intent(out) :: &
     205              :          res, dres_dlnRho, dres_dlnT
     206              :     real(dp), intent(out) :: dres_dxa(num_eos_d_dxa_results,s% species)
     207              :     integer, intent(out) :: ierr
     208              : 
     209              :     integer :: eos_calls
     210              : 
     211              :     include 'formats'
     212              : 
     213              :     ierr = 0
     214              : 
     215            0 :     if (s% doing_timing) s% timing_num_solve_eos_calls = s% timing_num_solve_eos_calls + 1
     216              : 
     217              :     call eosDT_get_T( &
     218              :        s% eos_handle, &
     219              :        s% species, s% chem_id, s% net_iso, xa, &
     220              :        logRho, i_logPtot, logP, logT_tol, logP_tol, MAX_ITER_FOR_SOLVE, logT_guess, &
     221              :        arg_not_provided, arg_not_provided, arg_not_provided, arg_not_provided, &
     222              :        logT, res, dres_dlnRho, dres_dlnT, &
     223            0 :        dres_dxa, eos_calls, ierr)
     224              : 
     225            0 :   end subroutine solve_eos_given_DP
     226              : 
     227              : 
     228              :   ! Solve for temperature & eos results data for a given density &
     229              :   ! entropy
     230              : 
     231            0 :   subroutine solve_eos_given_DS( &
     232            0 :        s, k, xa, &
     233              :        logRho, logS, logT_guess, logT_tol, logS_tol, &
     234            0 :        logT, res, dres_dlnRho, dres_dlnT, dres_dxa, &
     235              :        ierr)
     236              : 
     237            0 :     use eos_def
     238              :     use eos_lib, only: eosDT_get_T
     239              : 
     240              :     type (star_info), pointer :: s
     241              :     integer, intent(in) :: k  ! 0 indicates not for a particular cell.
     242              :     real(dp), intent(in) :: &
     243              :          xa(:), logRho, logS, &
     244              :          logT_guess, logT_tol, logS_tol
     245              :     real(dp), intent(out) :: logT
     246              :     real(dp), dimension(num_eos_basic_results), intent(out) :: &
     247              :          res, dres_dlnRho, dres_dlnT
     248              :     real(dp), intent(out) :: dres_dxa(num_eos_d_dxa_results,s% species)
     249              :     integer, intent(out) :: ierr
     250              : 
     251              :     integer :: eos_calls
     252              : 
     253              :     include 'formats'
     254              : 
     255              :     ierr = 0
     256              : 
     257              :     call eosDT_get_T( &
     258              :        s% eos_handle, &
     259              :        s% species, s% chem_id, s% net_iso, xa, &
     260              :        logRho, i_lnS, logS*ln10, &
     261              :        logT_tol, logS_tol*ln10, MAX_ITER_FOR_SOLVE, logT_guess,  &
     262              :        arg_not_provided, arg_not_provided, arg_not_provided, arg_not_provided, &
     263              :        logT, res, dres_dlnRho, dres_dlnT, dres_dxa, &
     264            0 :        eos_calls, ierr)
     265              : 
     266            0 :     if (s% doing_timing) s% timing_num_solve_eos_calls = s% timing_num_solve_eos_calls + eos_calls
     267              : 
     268            0 :   end subroutine solve_eos_given_DS
     269              : 
     270              : 
     271              :   ! Solve for density & eos results data given pressure & temperature
     272              : 
     273            0 :   subroutine solve_eos_given_PT( &
     274            0 :        s, k, xa, &
     275              :        logT, logP, logRho_guess, logRho_tol, logP_tol, &
     276            0 :        logRho, res, dres_dlnRho, dres_dlnT, dres_dxa, &
     277              :        ierr)
     278              : 
     279            0 :     use eos_def
     280              :     use eos_lib, only: eosDT_get_Rho
     281              : 
     282              :     type (star_info), pointer :: s
     283              :     integer, intent(in) :: k  ! 0 indicates not for a particular cell.
     284              :     real(dp), intent(in) :: &
     285              :          xa(:), logT, logP, &
     286              :          logRho_guess, logRho_tol, logP_tol
     287              :     real(dp), intent(out) :: logRho
     288              :     real(dp), dimension(num_eos_basic_results), intent(out) :: &
     289              :          res, dres_dlnRho, dres_dlnT
     290              :     real(dp), intent(out) :: dres_dxa(num_eos_d_dxa_results,s% species)
     291              :     integer, intent(out) :: ierr
     292              : 
     293              :     integer :: eos_calls
     294              : 
     295              :     include 'formats'
     296              : 
     297              :     ierr = 0
     298              : 
     299            0 :     if (s% doing_timing) s% timing_num_solve_eos_calls = s% timing_num_solve_eos_calls + 1
     300              : 
     301              :     call eosDT_get_Rho( &
     302              :        s% eos_handle, &
     303              :        s% species, s% chem_id, s% net_iso, xa, &
     304              :        logT, i_logPtot, logP, logRho_tol, logP_tol, MAX_ITER_FOR_SOLVE, logRho_guess, &
     305              :        arg_not_provided, arg_not_provided, arg_not_provided, arg_not_provided, &
     306              :        logRho, res, dres_dlnRho, dres_dlnT, &
     307            0 :        dres_dxa, eos_calls, ierr)
     308              : 
     309            0 :   end subroutine solve_eos_given_PT
     310              : 
     311              : 
     312              :   ! Solve for density & eos results data given gas pressure &
     313              :   ! temperature
     314              : 
     315            0 :   subroutine solve_eos_given_PgasT( &
     316            0 :        s, k, xa, &
     317              :        logT, logPgas, logRho_guess, logRho_tol, logPgas_tol, &
     318            0 :        logRho, res, dres_dlnRho, dres_dlnT, dres_dxa, &
     319              :        ierr)
     320              : 
     321            0 :     use eos_def
     322              :     use eos_lib, only: eosDT_get_Rho
     323              : 
     324              :     type (star_info), pointer :: s
     325              :     integer, intent(in) :: k  ! 0 indicates not for a particular cell.
     326              :     real(dp), intent(in) :: &
     327              :          xa(:), logT, logPgas, &
     328              :          logRho_guess, logRho_tol, logPgas_tol
     329              :     real(dp), intent(out) :: logRho
     330              :     real(dp), dimension(num_eos_basic_results), intent(out) :: &
     331              :          res, dres_dlnRho, dres_dlnT
     332              :     real(dp), intent(out) :: dres_dxa(num_eos_d_dxa_results,s% species)
     333              :     integer, intent(out) :: ierr
     334              : 
     335              :     integer :: eos_calls
     336              : 
     337              :     include 'formats'
     338              : 
     339              :     ierr = 0
     340              : 
     341              :     call eosDT_get_Rho( &
     342              :        s% eos_handle, &
     343              :        s% species, s% chem_id, s% net_iso, xa, &
     344              :        logT, i_lnPgas, logPgas*ln10, &
     345              :        logRho_tol, logPgas_tol*ln10, MAX_ITER_FOR_SOLVE, logRho_guess, &
     346              :        arg_not_provided, arg_not_provided, arg_not_provided, arg_not_provided, &
     347              :        logRho, res, dres_dlnRho, dres_dlnT, &
     348            0 :        dres_dxa, eos_calls, ierr)
     349            0 :     if (ierr /= 0 .and. s% report_ierr) then
     350            0 :        write(*,*) 'Call to eosDT_get_Rho failed in solve_eos_given_PgasT'
     351            0 :        write(*,2) 'logPgas', k, logPgas
     352            0 :        write(*,2) 'logT', k, logT
     353            0 :        write(*,2) 'logRho_guess', k, logRho_guess
     354              :     end if
     355              : 
     356            0 :     if (s% doing_timing) s% timing_num_solve_eos_calls = s% timing_num_solve_eos_calls + eos_calls
     357              : 
     358            0 :   end subroutine solve_eos_given_PgasT
     359              : 
     360              : 
     361              :   ! Solve for density & eos results data given gas pressure &
     362              :   ! temperature, with logRho_guess calculated automatically via an
     363              :   ! initial call to eos_gamma_PT_get
     364              : 
     365            0 :   subroutine solve_eos_given_PgasT_auto( &
     366            0 :        s, k, xa, &
     367              :        logT, logPgas, logRho_tol, logPgas_tol, &
     368            0 :        logRho, res, dres_dlnRho, dres_dlnT, dres_dxa, &
     369              :        ierr)
     370              : 
     371            0 :     use chem_lib, only: basic_composition_info
     372              :     use eos_def
     373              :     use eos_lib, only: eos_gamma_PT_get
     374              : 
     375              :     type (star_info), pointer :: s
     376              :     integer, intent(in) :: k  ! 0 indicates not for a particular cell.
     377              :     real(dp), intent(in) :: &
     378              :          xa(:), logT, logPgas, &
     379              :          logRho_tol, logPgas_tol
     380              :     real(dp), intent(out) :: logRho
     381              :     real(dp), dimension(num_eos_basic_results), intent(out) :: &
     382              :          res, dres_dlnRho, dres_dlnT
     383              :     real(dp), intent(out) :: dres_dxa(num_eos_d_dxa_results,s% species)
     384              :     integer, intent(out) :: ierr
     385              : 
     386              :     real(dp) :: rho_guess, logRho_guess, gamma
     387              : 
     388              :     ! compute composition info
     389              :     real(dp) :: Y, Z, X, abar, zbar, z2bar, z53bar, ye, mass_correction, sumx
     390              : 
     391              :     call basic_composition_info( &
     392              :        s% species, s% chem_id, xa, X, Y, Z, &
     393            0 :        abar, zbar, z2bar, z53bar, ye, mass_correction, sumx)
     394              : 
     395            0 :     gamma = 5d0/3d0
     396              :     call eos_gamma_PT_get( &
     397              :        s% eos_handle, abar, exp10(logPgas), logPgas, exp10(logT), logT, gamma, &
     398              :        rho_guess, logRho_guess, res, dres_dlnRho, dres_dlnT, &
     399            0 :        ierr)
     400            0 :     if (ierr /= 0) then
     401              :        ierr = 0
     402            0 :        logRho_guess = arg_not_provided
     403              :     end if
     404              : 
     405              :     call solve_eos_given_PgasT( &
     406              :        s, k, xa, &
     407              :        logT, logPgas, logRho_guess, logRho_tol, logPgas_tol, &
     408              :        logRho, res, dres_dlnRho, dres_dlnT, dres_dxa, &
     409            0 :        ierr)
     410              : 
     411            0 :   end subroutine solve_eos_given_PgasT_auto
     412              : 
     413              : end module eos_support
        

Generated by: LCOV version 2.0-1