LCOV - code coverage report
Current view: top level - star/private - hydro_vars.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 60.3 % 491 296
Test Date: 2025-05-08 18:23:42 Functions: 93.8 % 16 15

            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 hydro_vars
      21              : 
      22              :       use star_private_def
      23              :       use const_def, only: dp, i8, pi, ln10, boltz_sigma, clight, standard_cgrav, two_thirds, four_thirds, lsun, rsun, no_mixing
      24              :       use chem_def, only: chem_isos
      25              :       use utils_lib, only: mesa_error, is_bad
      26              : 
      27              :       implicit none
      28              : 
      29              :       private
      30              :       public :: set_vars_if_needed
      31              :       public :: set_vars
      32              :       public :: set_final_vars
      33              :       public :: update_vars
      34              :       public :: set_cgrav
      35              :       public :: set_hydro_vars
      36              :       public :: unpack_xh
      37              :       public :: set_Teff_info_for_eqns
      38              :       public :: set_Teff
      39              :       public :: get_surf_PT
      40              :       public :: set_grads
      41              : 
      42              :       logical, parameter :: dbg = .false.
      43              :       logical, parameter :: trace_setvars = .false.
      44              : 
      45              :       contains
      46              : 
      47          119 :       subroutine set_vars_if_needed(s, dt, str, ierr)
      48              :          type (star_info), pointer :: s
      49              :          real(dp), intent(in) :: dt
      50              :          character (len=*), intent(in) :: str
      51              :          integer, intent(out) :: ierr
      52           87 :          if (.not. s% need_to_setvars) then
      53              :             if (trace_setvars) write(*,*) '** skip set_vars ' // trim(str)
      54           55 :             s% num_skipped_setvars = s% num_skipped_setvars + 1
      55           55 :             return
      56              :          end if
      57              :          if (trace_setvars) write(*,*) 'set_vars ' // trim(str)
      58           32 :          call set_vars(s, dt, ierr)
      59              :       end subroutine set_vars_if_needed
      60              : 
      61              : 
      62           33 :       subroutine set_vars(s, dt, ierr)
      63              :          use star_utils, only: reset_starting_vectors
      64              :          type (star_info), pointer :: s
      65              :          real(dp), intent(in) :: dt
      66              :          integer, intent(out) :: ierr
      67              :          logical, parameter :: &
      68              :             skip_m_grav_and_grav = .false., &
      69              :             skip_net = .false., &
      70              :             skip_neu = .false., &
      71              :             skip_kap = .false., &
      72              :             skip_grads = .false., &
      73              :             skip_rotation = .false., &
      74              :             skip_brunt = .false., &
      75              :             skip_irradiation_heat = .false.
      76              :          logical :: skip_set_cz_bdy_mass, skip_mixing_info
      77           33 :          ierr = 0
      78           33 :          s% num_setvars = s% num_setvars + 1
      79              :          if (dbg) write(*,*) 'set_vars'
      80           33 :          call reset_starting_vectors(s)
      81           33 :          skip_set_cz_bdy_mass = .not. s% have_new_generation
      82           33 :          skip_mixing_info = .not. s% okay_to_set_mixing_info
      83              :          call set_some_vars( &
      84              :             s, skip_m_grav_and_grav, &
      85              :             skip_net, skip_neu, skip_kap, skip_grads, skip_rotation, &
      86              :             skip_brunt, skip_mixing_info, skip_set_cz_bdy_mass, skip_irradiation_heat, &
      87           33 :             dt, ierr)
      88           33 :       end subroutine set_vars
      89              : 
      90              : 
      91           11 :       subroutine set_final_vars(s, dt, ierr)
      92           33 :          use rates_def, only: num_rvs
      93              :          type (star_info), pointer :: s
      94              :          real(dp), intent(in) :: dt
      95              :          integer, intent(out) :: ierr
      96              : 
      97              :          logical :: &
      98              :             skip_basic_vars, &
      99              :             skip_micro_vars, &
     100              :             skip_m_grav_and_grav, &
     101              :             skip_eos, &
     102              :             skip_net, &
     103              :             skip_neu, &
     104              :             skip_kap, &
     105              :             skip_grads, &
     106              :             skip_rotation, &
     107              :             skip_brunt, &
     108              :             skip_other_cgrav, &
     109              :             skip_mixing_info, &
     110              :             skip_set_cz_bdy_mass, &
     111              :             skip_mlt
     112              :          integer :: nz, k
     113              : 
     114              :          include 'formats'
     115              : 
     116           11 :          ierr = 0
     117           11 :          nz = s% nz
     118              : 
     119           11 :          skip_grads = .false.
     120           11 :          skip_rotation = .false.
     121           11 :          skip_brunt = .false.
     122           11 :          skip_other_cgrav = .false.
     123           11 :          skip_set_cz_bdy_mass = .false.
     124           11 :          skip_m_grav_and_grav = .false.
     125           11 :          skip_mixing_info = .not. s% recalc_mix_info_after_evolve
     126              : 
     127              :          ! only need to do things that were skipped in set_vars_for_solver
     128              :          ! i.e., skip what it already did for the last solver iteration
     129           11 :          skip_basic_vars = .not. s% need_to_setvars
     130           11 :          skip_micro_vars = .not. s% need_to_setvars
     131           11 :          skip_kap = .not. s% need_to_setvars
     132           11 :          skip_neu = .not. s% need_to_setvars
     133           11 :          skip_net = .not. s% need_to_setvars
     134           11 :          skip_eos = .not. s% need_to_setvars
     135           11 :          skip_mlt = .not. s% need_to_setvars
     136              : 
     137           11 :          if (s% need_to_setvars) then
     138            0 :             s% num_setvars = s% num_setvars + 1
     139              :             if (trace_setvars) write(*,*) 'set_vars in set_final_vars'
     140              :          else
     141           11 :             s% num_skipped_setvars = s% num_skipped_setvars + 1
     142              :             if (trace_setvars) write(*,*) '** skip set_vars in set_final_vars'
     143              :          end if
     144              :          if (trace_setvars) write(*,*)
     145              : 
     146              :          call set_hydro_vars( &
     147              :             s, 1, nz, skip_basic_vars, &
     148              :             skip_micro_vars, skip_m_grav_and_grav, skip_eos, skip_net, skip_neu, &
     149              :             skip_kap, skip_grads, skip_rotation, skip_brunt, skip_other_cgrav, &
     150           11 :             skip_mixing_info, skip_set_cz_bdy_mass, skip_mlt, ierr)
     151           11 :          if (ierr /= 0) then
     152            0 :             if (s% report_ierr .or. dbg) &
     153            0 :                write(*,*) 'update_vars: set_hydro_vars returned ierr', ierr
     154              :             return
     155              :          end if
     156              : 
     157           11 :          if (s% op_split_burn) then
     158            0 :             do k = 1, nz
     159            0 :                if (s% T_start(k) >= s% op_split_burn_min_T) &
     160            0 :                   s% eps_nuc(k) = s% burn_avg_epsnuc(k)
     161              :             end do
     162              :          end if
     163              : 
     164           11 :       end subroutine set_final_vars
     165              : 
     166              : 
     167           33 :       subroutine set_some_vars( &
     168              :             s, skip_m_grav_and_grav, &
     169              :             skip_net, skip_neu, skip_kap, skip_grads, skip_rotation, &
     170              :             skip_brunt, skip_mixing_info, skip_set_cz_bdy_mass, skip_irradiation_heat, &
     171              :             dt, ierr)
     172           11 :          use star_utils, only: start_time, update_time
     173              :          type (star_info), pointer :: s
     174              :          logical, intent(in) :: &
     175              :             skip_m_grav_and_grav, &
     176              :             skip_net, skip_neu, skip_kap, skip_grads, &
     177              :             skip_rotation, skip_brunt, &
     178              :             skip_mixing_info, skip_set_cz_bdy_mass, skip_irradiation_heat
     179              :          real(dp), intent(in) :: dt
     180              :          integer, intent(out) :: ierr
     181              : 
     182              :          logical, parameter :: skip_other_cgrav = .false.
     183              :          logical, parameter :: skip_basic_vars = .false.
     184              :          logical, parameter :: skip_micro_vars = .false.
     185              :          logical, parameter :: skip_mlt = .false.
     186              :          logical, parameter :: skip_eos = .false.
     187              : 
     188              :          include 'formats'
     189              : 
     190              :          call update_vars(s, &
     191              :             skip_basic_vars, skip_micro_vars, &
     192              :             skip_m_grav_and_grav, skip_net, skip_neu, skip_kap, &
     193              :             skip_grads, skip_rotation, skip_brunt, skip_other_cgrav, &
     194              :             skip_mixing_info, skip_set_cz_bdy_mass, skip_irradiation_heat, &
     195           33 :             skip_mlt, skip_eos, dt, ierr)
     196           33 :          if (ierr /= 0) then
     197            0 :             if (s% report_ierr .or. dbg) &
     198            0 :                write(*,*) 'set_some_vars: update_vars returned ierr', ierr
     199              :             return
     200              :          end if
     201              : 
     202           33 :       end subroutine set_some_vars
     203              : 
     204              : 
     205           33 :       subroutine update_vars(s, &
     206              :             skip_basic_vars, skip_micro_vars, &
     207              :             skip_m_grav_and_grav, skip_net, skip_neu, skip_kap, &
     208              :             skip_grads, skip_rotation, skip_brunt, skip_other_cgrav, &
     209              :             skip_mixing_info, skip_set_cz_bdy_mass, skip_irradiation_heat, &
     210              :             skip_mlt, skip_eos, dt, ierr)
     211           33 :          use star_utils, only: eval_irradiation_heat
     212              :          type (star_info), pointer :: s
     213              :          logical, intent(in) :: &
     214              :             skip_basic_vars, skip_micro_vars, &
     215              :             skip_m_grav_and_grav, skip_net, skip_neu, skip_kap, skip_grads, &
     216              :             skip_rotation, skip_brunt, skip_other_cgrav, &
     217              :             skip_mixing_info, skip_set_cz_bdy_mass, skip_irradiation_heat, &
     218              :             skip_mlt, skip_eos
     219              :          real(dp), intent(in) :: dt
     220              :          integer, intent(out) :: ierr
     221              :          integer :: k, nz
     222              :          include 'formats'
     223              :          ierr = 0
     224           33 :          nz = s% nz
     225           33 :          if (s% doing_finish_load_model .or. .not. s% RSP_flag) then
     226           33 :             call unpack_xh(s,ierr)
     227           33 :             if (ierr /= 0) then
     228            0 :                if (s% report_ierr .or. dbg) &
     229            0 :                   write(*,*) 'after unpack ierr', ierr
     230            0 :                return
     231              :             end if
     232           33 :             if (.not. skip_mixing_info) then
     233        40766 :                s% mixing_type(1:nz) = no_mixing
     234        40766 :                s% adjust_mlt_gradT_fraction(1:nz) = -1
     235              :             end if
     236              :          end if
     237              : 
     238              :          call set_hydro_vars( &
     239              :             s, 1, nz, skip_basic_vars, &
     240              :             skip_micro_vars, skip_m_grav_and_grav, skip_eos, skip_net, skip_neu, &
     241              :             skip_kap, skip_grads, skip_rotation, skip_brunt, skip_other_cgrav, &
     242           33 :             skip_mixing_info, skip_set_cz_bdy_mass, skip_mlt, ierr)
     243           33 :          if (ierr /= 0) then
     244            0 :             if (s% report_ierr .or. dbg) &
     245            0 :                write(*,*) 'update_vars: set_hydro_vars returned ierr', ierr
     246            0 :             return
     247              :          end if
     248              : 
     249           33 :          if (s% use_other_momentum) then
     250            0 :             call s% other_momentum(s% id, ierr)
     251            0 :             if (ierr /= 0) then
     252            0 :                if (s% report_ierr .or. dbg) &
     253            0 :                   write(*,*) 'update_vars: other_momentum returned ierr', ierr
     254            0 :                return
     255              :             end if
     256              :          end if
     257              : 
     258           33 :          if (.not. skip_irradiation_heat) then
     259           33 :             if (s% irradiation_flux /= 0) then
     260            0 :                do k=1,nz
     261            0 :                   s% irradiation_heat(k) = eval_irradiation_heat(s,k)
     262              :                end do
     263              :             else
     264        40766 :                s% irradiation_heat(1:nz) = 0
     265              :             end if
     266              :          end if
     267              : 
     268           33 :       end subroutine update_vars
     269              : 
     270              : 
     271           33 :       subroutine unpack_xh(s,ierr)
     272           33 :          use star_utils, only: set_qs, set_dm_bar, set_m_and_dm
     273              :          type (star_info), pointer :: s
     274              :          integer, intent(out) :: ierr
     275              :          integer :: i_lnd, i_lnT, i_lnR, i_w, i_Hp, &
     276              :             i_lum, i_v, i_u, i_alpha_RTI, i_Et_RSP, &
     277              :             j, k, species, nvar_chem, nz, k_below_just_added
     278              :          include 'formats'
     279           33 :          ierr = 0
     280           33 :          nz = s% nz
     281           33 :          k_below_just_added = 1
     282           33 :          species = s% species
     283           33 :          nvar_chem = s% nvar_chem
     284           33 :          i_lnd = s% i_lnd
     285           33 :          i_lnT = s% i_lnT
     286           33 :          i_lnR = s% i_lnR
     287           33 :          i_lum = s% i_lum
     288           33 :          i_w = s% i_w
     289           33 :          i_Hp = s% i_Hp
     290           33 :          i_v = s% i_v
     291           33 :          i_u = s% i_u
     292           33 :          i_alpha_RTI = s% i_alpha_RTI
     293           33 :          i_Et_RSP = s% i_Et_RSP
     294              : 
     295          165 :          do j=1,s% nvar_hydro
     296          165 :             if (j == i_lnd) then
     297        40766 :                do k=1,nz
     298        40733 :                   s% lnd(k) = s% xh(i_lnd,k)
     299        40766 :                   s% rho(k) = exp(s% lnd(k))
     300              :                end do
     301        40766 :                s% dxh_lnd(1:nz) = 0d0
     302           99 :             else if (j == i_lnT) then
     303        40766 :                do k=1,nz
     304        40733 :                   s% lnT(k) = s% xh(i_lnT,k)
     305        40766 :                   s% T(k) = exp(s% lnT(k))
     306              :                end do
     307        40766 :                s% dxh_lnT(1:nz) = 0d0
     308           66 :             else if (j == i_lnR) then
     309        40766 :                do k=1,nz
     310        40733 :                   s% lnR(k) = s% xh(i_lnR,k)
     311        40766 :                   s% r(k) = exp(s% lnR(k))
     312              :                end do
     313        40766 :                s% dxh_lnR(1:nz) = 0d0
     314           33 :             else if (j == i_w) then
     315            0 :                do k=1,nz
     316            0 :                   s% w(k) = s% xh(i_w, k)
     317            0 :                   if (s% w(k) < 0d0) then
     318              :                      !write(*,4) 'unpack: fix w < 0', k, &
     319              :                      !   s% solver_iter, s% model_number, s% w(k)
     320            0 :                      s% w(k) = s% RSP2_w_fix_if_neg
     321              :                   end if
     322              :                end do
     323           33 :             else if (j == i_Hp) then
     324            0 :                do k=1,nz
     325            0 :                   s% Hp_face(k) = s% xh(i_Hp, k)
     326              :                end do
     327           33 :             else if (j == i_lum) then
     328        40766 :                do k=1,nz
     329        40766 :                   s% L(k) = s% xh(i_lum, k)
     330              :                end do
     331            0 :             else if (j == i_v) then
     332            0 :                do k=1,nz
     333            0 :                   s% v(k) = s% xh(i_v,k)
     334            0 :                   s% dxh_v(k) = 0d0
     335              :                end do
     336            0 :             else if (j == i_u) then
     337            0 :                do k=1,nz
     338            0 :                   s% u(k) = s% xh(i_u,k)
     339            0 :                   s% dxh_u(k) = 0d0
     340              :                end do
     341            0 :             else if (j == i_alpha_RTI) then
     342            0 :                do k=1,nz
     343            0 :                   s% alpha_RTI(k) = max(0d0, s% xh(i_alpha_RTI,k))
     344            0 :                   s% dxh_alpha_RTI(k) = 0d0
     345              :                end do
     346            0 :             else if (j == i_Et_RSP) then
     347            0 :                do k=1,nz
     348            0 :                   s% RSP_Et(k) = max(0d0,s% xh(i_Et_RSP,k))
     349              :                end do
     350              :             end if
     351              :          end do
     352              : 
     353           33 :          if (i_lum == 0 .and. .not. s% RSP_flag) s% L(1:nz) = 0d0
     354        40766 :          if (i_v == 0) s% v(1:nz) = 0d0
     355        40766 :          if (i_u == 0) s% u(1:nz) = 0d0
     356        40766 :          if (i_w == 0) s% w(1:nz) = 0d0
     357        40766 :          if (i_Hp == 0) s% Hp_face(1:nz) = 0d0
     358              : 
     359           33 :          call set_qs(s, nz, s% q, s% dq, ierr)
     360           33 :          if (ierr /= 0) then
     361            0 :             write(*,*) 'update_vars failed in set_qs'
     362              :             return
     363              :          end if
     364           33 :          call set_m_and_dm(s)
     365           33 :          call set_dm_bar(s, s% nz, s% dm, s% dm_bar)
     366              : 
     367           33 :       end subroutine unpack_xh
     368              : 
     369              : 
     370            0 :       subroutine set_Teff(s, ierr)
     371              :          type (star_info), pointer :: s
     372              :          integer, intent(out) :: ierr
     373              :          real(dp) :: r_phot, L_surf
     374              :          logical, parameter :: skip_partials = .false., &
     375              :             need_atm_Psurf = .false., need_atm_Tsurf = .false.
     376              :          real(dp) :: Teff, &
     377              :             lnT_surf, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     378              :             lnP_surf, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap
     379              :          ierr = 0
     380              :          call set_Teff_info_for_eqns(s, skip_partials, &
     381              :             need_atm_Psurf, need_atm_Tsurf, r_phot, L_surf, Teff, &
     382              :             lnT_surf, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     383              :             lnP_surf, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap, &
     384            0 :             ierr)
     385           33 :       end subroutine set_Teff
     386              : 
     387              : 
     388           44 :       subroutine set_Teff_info_for_eqns(s, skip_partials, &
     389              :             need_atm_Psurf_in, need_atm_Tsurf_in, r_surf, L_surf, Teff, &
     390              :             lnT_surf, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     391              :             lnP_surf, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap, &
     392              :             ierr)
     393              :          use star_utils, only: set_phot_info
     394              :          use atm_lib, only: atm_Teff
     395              :          use starspots, only: starspot_tweak_PT, starspot_restore_PT
     396              :          type (star_info), pointer :: s
     397              :          logical, intent(in) :: skip_partials, &
     398              :             need_atm_Psurf_in, need_atm_Tsurf_in
     399              :          real(dp), intent(out) :: r_surf, L_surf, Teff, &
     400              :             lnT_surf, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     401              :             lnP_surf, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap
     402              :          integer, intent(out) :: ierr
     403              :          logical :: need_atm_Psurf, need_atm_Tsurf
     404              : 
     405              :          include 'formats'
     406              : 
     407           44 :          need_atm_Psurf = need_atm_Psurf_in
     408           44 :          need_atm_Tsurf = need_atm_Tsurf_in
     409              : 
     410           44 :          ierr = 0
     411              : 
     412           44 :          r_surf = s% r(1)
     413           44 :          L_surf = s% L(1)
     414              : 
     415           44 :          s% P_surf = s% Peos(1)
     416           44 :          s% T_surf = s% T(1)
     417              : 
     418           44 :          call set_phot_info(s)  ! sets Teff using L_phot and R_phot
     419           44 :          Teff = s% Teff
     420              : 
     421           44 :          if (s% RSP_flag) then
     422            0 :             lnT_surf = s% lnT(1)
     423            0 :             dlnT_dL = 0d0
     424            0 :             dlnT_dlnR = 0d0
     425            0 :             dlnT_dlnM = 0d0
     426            0 :             dlnT_dlnkap = 0d0
     427            0 :             lnP_surf = s% lnPeos(1)
     428            0 :             dlnP_dL = 0d0
     429            0 :             dlnP_dlnR = 0d0
     430            0 :             dlnP_dlnM = 0d0
     431            0 :             dlnP_dlnkap = 0d0
     432            0 :             return
     433              :          end if
     434              : 
     435           44 :          if (s% use_other_surface_PT) then
     436              :             call s% other_surface_PT( &
     437              :                s% id, skip_partials, &
     438              :                lnT_surf, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     439              :                lnP_surf, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap, &
     440            0 :                ierr)
     441              :          else
     442              :             ! starspot YREC routine
     443           44 :             if (s% do_starspots) then
     444            0 :                need_atm_Psurf = .true.
     445            0 :                need_atm_Tsurf = .true.
     446            0 :                call starspot_tweak_PT(s)
     447              :             end if
     448              :             call get_surf_PT( &
     449              :                s, skip_partials, need_atm_Psurf, need_atm_Tsurf, &
     450              :                lnT_surf, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     451              :                lnP_surf, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap, &
     452           44 :                ierr)
     453              :             ! starspot YREC routine
     454           44 :             if (s% do_starspots) then
     455            0 :                call starspot_restore_PT(s)
     456              :             end if
     457              :          end if
     458           44 :          if (ierr /= 0) then
     459            0 :             if (s% report_ierr) then
     460            0 :                write(*,*) 'error in get_surf_PT'
     461              :             end if
     462            0 :             return
     463              :          end if
     464           44 :          s% T_surf = exp(lnT_surf)
     465           44 :          s% P_surf = exp(lnP_surf)
     466              : 
     467           44 :          call set_phot_info(s)  ! s% T_surf might have changed so call again
     468              : 
     469           44 :       end subroutine set_Teff_info_for_eqns
     470              : 
     471              : 
     472           77 :       subroutine set_hydro_vars( &
     473              :             s, nzlo, nzhi, skip_basic_vars, skip_micro_vars, skip_m_grav_and_grav, &
     474              :             skip_eos, skip_net, skip_neu, skip_kap, skip_grads, skip_rotation, &
     475              :             skip_brunt, skip_other_cgrav, &
     476              :             skip_mixing_info, skip_set_cz_bdy_mass, skip_mlt, ierr)
     477           44 :          use atm_lib, only: atm_eval_T_tau_dq_dtau
     478              :          use atm_support, only: get_T_tau_id
     479              :          use micro, only: set_micro_vars
     480              :          use turb_info, only: set_mlt_vars, check_for_redo_MLT
     481              :          use star_utils, only: start_time, update_time, &
     482              :             set_m_grav_and_grav, set_scale_height, get_tau, &
     483              :             set_abs_du_div_cs, set_conv_time_scales
     484              :          use hydro_rotation, only: set_rotation_info, compute_j_fluxes_and_extra_jdot
     485              :          use brunt, only: do_brunt_B, do_brunt_N2
     486              :          use mix_info, only: set_mixing_info
     487              :          use hydro_rsp2, only: set_RSP2_vars
     488              : 
     489              :          type (star_info), pointer :: s
     490              :          integer, intent(in) :: nzlo, nzhi
     491              :          logical, intent(in) :: &
     492              :             skip_basic_vars, skip_micro_vars, skip_m_grav_and_grav, &
     493              :             skip_eos, skip_net, skip_neu, skip_kap, skip_brunt, &
     494              :             skip_grads, skip_rotation, skip_other_cgrav, &
     495              :             skip_mixing_info, skip_set_cz_bdy_mass, skip_mlt
     496              :          integer, intent(out) :: ierr
     497              : 
     498              :          integer :: nz, k, T_tau_id
     499              :          integer(i8) :: time0
     500              :          logical, parameter :: dbg = .false.
     501           77 :          real(dp) :: total
     502              : 
     503              :          include 'formats'
     504              : 
     505              :          if (dbg) write(*,*) 'set_hydro_vars', nzlo, nzhi
     506           77 :          if (s% doing_timing) call start_time(s, time0, total)
     507              : 
     508           77 :          ierr = 0
     509           77 :          nz = s% nz
     510              : 
     511           77 :          if (.not. skip_basic_vars) then
     512              :             if (dbg) write(*,*) 'call set_basic_vars'
     513           33 :             call set_basic_vars(s, nzlo, nzhi, ierr)
     514           33 :             if (failed('set_basic_vars')) return
     515              :          end if
     516              : 
     517           77 :          if (.not. skip_micro_vars) then
     518              :             if (dbg) write(*,*) 'call set_micro_vars'
     519              :             call set_micro_vars(s, nzlo, nzhi, &
     520           66 :                skip_eos, skip_net, skip_neu, skip_kap, ierr)
     521           66 :             if (failed('set_micro_vars')) return
     522              :          end if
     523              : 
     524           77 :          if (.not. skip_other_cgrav) call set_cgrav(s, ierr)
     525              : 
     526           77 :          call get_tau(s, ierr)
     527           77 :          if (failed('get_tau')) return
     528              : 
     529           77 :          if (.not. skip_m_grav_and_grav) then
     530              :             ! don't change m_grav or grav during solver iterations
     531              :             if (dbg) write(*,*) 'call set_m_grav_and_grav'
     532           44 :             call set_m_grav_and_grav(s)
     533              :          end if
     534              : 
     535              :          if (dbg) write(*,*) 'call set_scale_height'
     536           77 :          call set_scale_height(s)
     537              : 
     538           77 :          if (s% rotation_flag .and. (.not. skip_rotation .or. s% w_div_wc_flag)) then
     539              :             if (dbg) write(*,*) 'call set_rotation_info'
     540            0 :             call set_rotation_info(s, .true., ierr)
     541            0 :             if (failed('set_rotation_info')) return
     542              :          end if
     543              : 
     544           77 :          if (.not. skip_grads) then
     545              :             if (dbg) write(*,*) 'call do_brunt_B'
     546           44 :             call do_brunt_B(s, nzlo, nzhi, ierr)  ! for unsmoothed_brunt_B
     547           44 :             if (failed('do_brunt_B')) return
     548              :             if (dbg) write(*,*) 'call set_grads'
     549           44 :             call set_grads(s, ierr)
     550           44 :             if (failed('set_grads')) return
     551           44 :             call set_conv_time_scales(s)  ! uses brunt_B
     552              :          end if
     553              : 
     554           77 :          if (.not. skip_mixing_info) then
     555           33 :             if (.not. s% RSP2_flag) then
     556              :                if (dbg) write(*,*) 'call other_adjust_mlt_gradT_fraction'
     557           33 :                call s% other_adjust_mlt_gradT_fraction(s% id,ierr)
     558           33 :                if (failed('other_adjust_mlt_gradT_fraction')) return
     559              :             end if
     560              :             if (dbg) write(*,*) 'call set_abs_du_div_cs'
     561           33 :             call set_abs_du_div_cs(s)
     562              :          end if
     563              : 
     564           77 :          if (.not. skip_mlt .and. .not. s% RSP_flag) then
     565              : 
     566           66 :             if (.not. skip_mixing_info) then
     567           33 :                if (s% make_gradr_sticky_in_solver_iters) then
     568            0 :                   s% fixed_gradr_for_rest_of_solver_iters(nzlo:nzhi) = .false.
     569              :                end if
     570        40766 :                s% alpha_mlt(nzlo:nzhi) = s% mixing_length_alpha
     571           33 :                if (s% use_other_alpha_mlt) then
     572            0 :                   call s% other_alpha_mlt(s% id, ierr)
     573            0 :                   if (ierr /= 0) then
     574            0 :                      if (s% report_ierr .or. dbg) &
     575            0 :                         write(*,*) 'other_alpha_mlt returned ierr', ierr
     576            0 :                      return
     577              :                   end if
     578              :                end if
     579              :             end if
     580              : 
     581           66 :             if (s% use_other_gradr_factor) then
     582              :                if (dbg) write(*,*) 'call other_gradr_factor'
     583            0 :                call s% other_gradr_factor(s% id, ierr)
     584            0 :                if (failed('other_gradr_factor')) return
     585           66 :             else if (s% use_T_tau_gradr_factor) then
     586              :                if (dbg) write(*,*) 'call use_T_tau_gradr_factor'
     587            0 :                call get_T_tau_id(s% atm_T_tau_relation, T_tau_id, ierr)
     588            0 :                do k = nzlo, nzhi
     589              :                   ! slightly inconsistent to use s% tau, defined at
     590              :                   ! faces, with s% gradr, which is a cell average
     591              :                   ! but this performs better than using
     592              :                   !    taumid = (tau(k)+tau(k+1))/2
     593            0 :                   call atm_eval_T_tau_dq_dtau(T_tau_id, s% tau(k), s% gradr_factor(k), ierr)
     594            0 :                   s% gradr_factor(k) = 1.0_dp + s% gradr_factor(k)
     595              :                end do
     596            0 :                if (failed('use_T_tau_gradr_factor')) return
     597              :             else
     598        80060 :                s% gradr_factor(nzlo:nzhi) = 1d0
     599              :             end if
     600              : 
     601           66 :             call set_mlt_vars(s, nzlo, nzhi, ierr)
     602           66 :             if (failed('set_mlt_vars')) return
     603              :             if (dbg) write(*,*) 'call check_for_redo_MLT'
     604              : 
     605           66 :             call check_for_redo_MLT(s, nzlo, nzhi, ierr)
     606           66 :             if (failed('check_for_redo_MLT')) return
     607              : 
     608              :          end if
     609              : 
     610           77 :          if (.not. skip_brunt) then  ! skip_brunt during solver iterations
     611              :             if (dbg) write(*,*) 'call do_brunt_N2'
     612           44 :             call do_brunt_N2(s, nzlo, nzhi, ierr)
     613           44 :             if (failed('do_brunt_N2')) return
     614              :          end if
     615              : 
     616           77 :          if (.not. skip_mixing_info) then
     617              :             if (dbg) write(*,*) 'call set_mixing_info'
     618           33 :             call set_mixing_info(s, skip_set_cz_bdy_mass, ierr)
     619           33 :             if (ierr /= 0) return
     620              :          end if
     621              : 
     622           77 :          if (s% j_rot_flag) then
     623            0 :             call compute_j_fluxes_and_extra_jdot(s% id, ierr)
     624            0 :             if (ierr /= 0) then
     625            0 :                write(*,*) 'failed in compute_j_fluxes'
     626              :             end if
     627              :          end if
     628              : 
     629           77 :          if (s% RSP2_flag) then
     630            0 :             call set_RSP2_vars(s,ierr)
     631            0 :             if (ierr /= 0) then
     632            0 :                if (len_trim(s% retry_message) == 0) s% retry_message = 'set_RSP2_vars failed'
     633            0 :                if (s% report_ierr) write(*,*) 'ierr from set_RSP2_vars'
     634            0 :                return
     635              :             end if
     636              :          end if
     637              : 
     638           77 :          if (s% doing_timing) &
     639            0 :             call update_time(s, time0, total, s% time_set_hydro_vars)
     640              : 
     641           77 :          s% need_to_setvars = .false.
     642              : 
     643              : 
     644              :          contains
     645              : 
     646          473 :          logical function failed(str)
     647              :             character (len=*), intent(in) :: str
     648          473 :             if (ierr == 0) then
     649              :                failed = .false.
     650              :                return
     651              :             end if
     652            0 :             if (s% report_ierr .or. dbg) &
     653            0 :                write(*,*) 'set_hydro_vars failed in call to ' // trim(str)
     654              :             failed = .true.
     655           77 :          end function failed
     656              : 
     657              :       end subroutine set_hydro_vars
     658              : 
     659              : 
     660              :       subroutine check_rs(s, ierr)
     661              :          type (star_info), pointer :: s
     662              :          integer, intent(out) :: ierr
     663              :          integer :: k
     664              :          logical :: okay
     665              :          include 'formats'
     666              :          ierr = 0
     667              :          okay = .true.
     668              :          do k=2, s% nz
     669              :             if (s% r(k) > s% r(k-1)) then
     670              :                if (s% report_ierr) then
     671              :                   write(*,2) 's% r(k) > s% r(k-1)', k, &
     672              :                      s% r(k)/Rsun, s% r(k-1)/Rsun, s% r(k)/Rsun-s% r(k-1)/Rsun
     673              :                end if
     674              :                okay = .false.
     675              :             end if
     676              :          end do
     677              :          if (okay) return
     678              :          s% retry_message = 'invalid values for r'
     679              :          ierr = -1
     680              :          if (s% report_ierr) write(*,*)
     681              :       end subroutine check_rs
     682              : 
     683              : 
     684           33 :       subroutine set_basic_vars(s, nzlo, nzhi, ierr)
     685              :          use star_utils, only: set_rv_info, set_rmid
     686              :          type (star_info), pointer :: s
     687              :          integer, intent(in) :: nzlo, nzhi
     688              :          integer, intent(out) :: ierr
     689              :          integer :: j, k, species, nz
     690           33 :          real(dp) :: twoGmrc2, sum_xa
     691              : 
     692              :          include 'formats'
     693              : 
     694              :          if (dbg) write(*,4) 'enter set_basic_vars: nzlo, nzhi, nz', &
     695              :             nzlo, nzhi, s% nz
     696           33 :          ierr = 0
     697           33 :          nz = s% nz
     698           33 :          species = s% species
     699           33 :          s% L_phot = s% L(1)/Lsun
     700           33 :          if (.not. s% using_velocity_time_centering) then
     701           33 :             s% d_vc_dv = 1d0
     702              :          else
     703            0 :             s% d_vc_dv = 0.5d0
     704              :          end if
     705              : 
     706           33 : !$OMP PARALLEL DO PRIVATE(j,k,twoGmrc2,sum_xa) SCHEDULE(dynamic,2)
     707              :          do k=nzlo, nzhi
     708              :             if (s% lnd_start(k) < -1d90) then
     709              :                s% lnd_start(k) = s% lnd(k)
     710              :                s% rho_start(k) = s% rho(k)
     711              :             end if
     712              :             if (s% T_start(k) < 0d0) then
     713              :                s% T_start(k) = s% T(k)
     714              :                s% lnT_start(k) = s% lnT(k)
     715              :             end if
     716              :             if (s% v_flag) then
     717              :                if (s% v_start(k) < -1d90) s% v_start(k) = s% v(k)
     718              :             end if
     719              :             if (s% u_flag) then
     720              :                if (s% u_start(k) < -1d90) s% u_start(k) = s% u(k)
     721              :             end if
     722              :             if (s% RTI_flag) then
     723              :                if (s% alpha_RTI_start(k) < -1d90) &
     724              :                   s% alpha_RTI_start(k) = s% alpha_RTI(k)
     725              :             end if
     726              :             if (s% RSP_flag) then
     727              :                s% RSP_w(k) = sqrt(s% RSP_Et(k))
     728              :                if (s% RSP_w_start(k) < -1d90) then
     729              :                   s% RSP_w_start(k) = s% RSP_w(k)
     730              :                end if
     731              :             end if
     732              :             if (s% r_start(k) < 0) s% r_start(k) = s% r(k)
     733              :             call set_rv_info(s,k)
     734              :             do j=1,species
     735              :                s% xa(j,k) = max(0d0, min(1d0, s% xa(j,k)))
     736              :             end do
     737              :             sum_xa = sum(s% xa(1:species,k))
     738              :             if (abs(sum_xa - 1d0) > 1d-12) then
     739              :                do j=1,species
     740              :                   s% xa(j,k) = s% xa(j,k)/sum_xa
     741              :                end do
     742              :             end if
     743              :          end do
     744              : !$OMP END PARALLEL DO
     745              : 
     746           33 :          call set_rmid(s, nzlo, nzhi, ierr)
     747              : 
     748           33 :       end subroutine set_basic_vars
     749              : 
     750              : 
     751           44 :       subroutine set_cgrav(s, ierr)
     752              :          type (star_info), pointer :: s
     753              :          integer, intent(out) :: ierr
     754           44 :          if (s% use_other_cgrav) then
     755            0 :             call s% other_cgrav(s% id, ierr)
     756            0 :             if (ierr /= 0) then
     757            0 :                if (s% report_ierr .or. dbg) &
     758            0 :                   write(*,*) 'other_cgrav returned ierr', ierr
     759            0 :                return
     760              :             end if
     761              :          else
     762        53864 :             s% cgrav(1:s% nz) = standard_cgrav
     763              :          end if
     764           33 :       end subroutine set_cgrav
     765              : 
     766              : 
     767           44 :       subroutine get_surf_PT( &
     768              :             s, skip_partials, &
     769              :             need_atm_Psurf, need_atm_Tsurf, &
     770              :             lnT_surf, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     771              :             lnP_surf, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap, &
     772              :             ierr)
     773              : 
     774              :          use atm_support, only: get_atm_PT
     775              :          use atm_def, only: star_debugging_atm_flag, &
     776              :             atm_test_partials_val, atm_test_partials_dval_dx
     777              :          use chem_def
     778              :          use eos_lib, only: Radiation_Pressure
     779              : 
     780              :          type (star_info), pointer :: s
     781              :          logical, intent(in) :: skip_partials, &
     782              :             need_atm_Psurf, need_atm_Tsurf
     783              :          real(dp), intent(out) :: &
     784              :             lnT_surf, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     785              :             lnP_surf, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap
     786              :          integer, intent(out) :: ierr
     787              : 
     788           44 :          real(dp) :: L_surf
     789           44 :          real(dp) :: R_surf
     790           44 :          real(dp) :: Teff
     791           44 :          real(dp) :: tau_surf
     792           44 :          real(dp) :: Teff4
     793           44 :          real(dp) :: T_surf4
     794           44 :          real(dp) :: T_surf
     795           44 :          real(dp) :: P_surf_atm
     796           44 :          real(dp) :: P_surf
     797           44 :          real(dp) :: Pextra
     798           44 :          real(dp) :: kap_surf
     799           44 :          real(dp) :: M_surf
     800              : 
     801              :          include 'formats'
     802              : 
     803              :          ! Set up stellar surface parameters
     804              : 
     805           44 :          L_surf = s% L(1)
     806           44 :          R_surf = s% r(1)
     807           44 :          kap_surf = s% opacity(1)
     808           44 :          M_surf = s% m(1)
     809           44 :          Teff = s% Teff
     810              : 
     811              :          ! Initialize partials
     812           44 :          dlnT_dL = 0._dp; dlnT_dlnR = 0._dp; dlnT_dlnM = 0._dp; dlnT_dlnkap = 0._dp
     813           44 :          dlnP_dL = 0._dp; dlnP_dlnR = 0._dp; dlnP_dlnM = 0._dp; dlnP_dlnkap = 0._dp
     814              : 
     815              :          ! Evaluate the surface optical depth
     816              : 
     817           44 :          tau_surf = s% tau_factor*s% tau_base  ! tau at outer edge of cell 1
     818           44 :          if (is_bad(tau_surf)) then
     819            0 :             write(*,1) 's% tau_factor', s% tau_factor
     820            0 :             write(*,1) 's% tau_base', s% tau_base
     821            0 :             write(*,1) 'tau_surf', tau_surf
     822            0 :             call mesa_error(__FILE__,__LINE__,'bad tau_surf in get_surf_PT')
     823              :          end if
     824              : 
     825              :          ! Evaluate surface temperature and pressure
     826              : 
     827           44 :          if (.not. (need_atm_Psurf .or. need_atm_Tsurf)) then
     828              : 
     829              :             ! Special-case boundary condition
     830              : 
     831            0 :             lnP_surf = s% lnPeos_start(1)
     832            0 :             if (is_bad(lnP_surf)) lnP_surf = 0._dp
     833            0 :             T_surf = s% T_start(1)
     834            0 :             lnT_surf = log(T_surf)
     835            0 :             T_surf4 = T_surf*T_surf*T_surf*T_surf
     836            0 :             Teff = pow(four_thirds*T_surf4/(tau_surf + two_thirds), 0.25_dp)
     837              : 
     838            0 :             if (.not. skip_partials) then
     839            0 :                dlnT_dL = 0._dp; dlnT_dlnR = 0._dp; dlnT_dlnM = 0._dp; dlnT_dlnkap = 0._dp
     840            0 :                dlnP_dL = 0._dp; dlnP_dlnR = 0._dp; dlnP_dlnM = 0._dp; dlnP_dlnkap = 0._dp
     841              :             end if
     842              : 
     843              :          else
     844              :             ! Evaluate temperature and pressure based on atm_option
     845              :             ! (yes, we might want to translate atm_option into an integer,
     846              :             ! but these string comparisons are cheap)
     847              : 
     848              :             ! The first few are special, 'trivial-atmosphere' options
     849              : 
     850           44 :             select case (s% atm_option)
     851              : 
     852              :             case ('fixed_Teff')
     853              : 
     854              :                ! set Tsurf from Eddington T-tau relation
     855              :                !     for current surface tau and Teff = `atm_fixed_Teff`.
     856              :                ! set Psurf = Radiation_Pressure(Tsurf)
     857              : 
     858            0 :                Teff = s% atm_fixed_Teff
     859            0 :                Teff4 = Teff*Teff*Teff*Teff
     860            0 :                T_surf = pow(3._dp/4._dp*Teff4*(tau_surf + 2._dp/3._dp), 0.25_dp)
     861            0 :                lnT_surf = log(T_surf)
     862            0 :                lnP_surf = Radiation_Pressure(T_surf)
     863              : 
     864            0 :                if (.not. skip_partials) then
     865            0 :                   dlnT_dL = 0._dp; dlnT_dlnR = 0._dp; dlnT_dlnM = 0._dp; dlnT_dlnkap = 0._dp
     866            0 :                   dlnP_dL = 0._dp; dlnP_dlnR = 0._dp; dlnP_dlnM = 0._dp; dlnP_dlnkap = 0._dp
     867              :                end if
     868              : 
     869              :             case ('fixed_Tsurf')
     870              : 
     871              :                ! set Teff from Eddington T-tau relation for given
     872              :                ! Tsurf and tau=2/3 set Psurf =
     873              :                ! Radiation_Pressure(Tsurf)
     874              : 
     875            0 :                T_surf = s% atm_fixed_Tsurf
     876            0 :                lnT_surf = log(T_surf)
     877            0 :                T_surf4 = T_surf*T_surf*T_surf*T_surf
     878            0 :                Teff = pow(4._dp/3._dp*T_surf4/(tau_surf + 2._dp/3._dp), 0.25_dp)
     879            0 :                lnP_surf = Radiation_Pressure(T_surf)
     880              : 
     881            0 :                if (.not. skip_partials) then
     882            0 :                   dlnT_dL = 0._dp; dlnT_dlnR = 0._dp; dlnT_dlnM = 0._dp; dlnT_dlnkap = 0._dp
     883            0 :                   dlnP_dL = 0._dp; dlnP_dlnR = 0._dp; dlnP_dlnM = 0._dp; dlnP_dlnkap = 0._dp
     884              :                end if
     885              : 
     886              :             case ('fixed_Psurf')
     887              : 
     888              :                ! set Teff from L and R using L = 4*pi*R^2*boltz_sigma*T^4.
     889              :                ! set Tsurf using Eddington T-tau relation
     890              : 
     891            0 :                if (L_surf < 0._dp) then
     892            0 :                   if (s% report_ierr) then
     893            0 :                      write(*,2) 'get_surf_PT: L_surf <= 0', s% model_number, L_surf
     894              :                   end if
     895            0 :                   if (s% stop_for_bad_nums) call mesa_error(__FILE__,__LINE__)
     896            0 :                   s% retry_message = 'L_surf < 0'
     897            0 :                   ierr = -1
     898            0 :                   return
     899              :                end if
     900              : 
     901            0 :                lnP_surf = safe_log(s% atm_fixed_Psurf)
     902            0 :                if (R_surf <= 0._dp) then
     903            0 :                   T_surf4 = 1._dp
     904            0 :                   T_surf = 1._dp
     905            0 :                   lnT_surf = 0._dp
     906            0 :                   if (.not. skip_partials) then
     907            0 :                      dlnT_dlnR = 0._dp
     908            0 :                      dlnT_dL = 0._dp
     909              :                   end if
     910            0 :                   Teff = s% T(1)
     911              :                else
     912            0 :                   Teff = pow(L_surf/(4._dp*pi*R_surf*R_surf*boltz_sigma), 0.25_dp)
     913            0 :                   T_surf4 = 3d0/4d0*pow(Teff, 4.d0)*(tau_surf + 2._dp/3._dp)
     914            0 :                   T_surf = pow(T_surf4, 0.25_dp)
     915            0 :                   lnT_surf = log(T_surf)
     916            0 :                   if (.not. skip_partials) then
     917            0 :                      dlnT_dlnR = -0.5_dp
     918            0 :                      dlnT_dL = 1._dp/(4._dp*L_surf)
     919              :                   end if
     920              :                end if
     921              : 
     922            0 :                if (.not. skip_partials) then
     923            0 :                   dlnT_dlnM = 0._dp; dlnT_dlnkap = 0._dp
     924            0 :                   dlnP_dL = 0._dp; dlnP_dlnR = 0._dp; dlnP_dlnM = 0._dp; dlnP_dlnkap = 0._dp
     925              :                end if
     926              : 
     927              :             case ('fixed_Psurf_and_Tsurf')
     928              : 
     929            0 :                lnP_surf = safe_log(s% atm_fixed_Psurf)
     930            0 :                T_surf = s% atm_fixed_Tsurf
     931            0 :                lnT_surf = log(T_surf)
     932            0 :                T_surf4 = T_surf*T_surf*T_surf*T_surf
     933            0 :                Teff = pow(4d0/3d0*T_surf4/(tau_surf + 2d0/3d0), 0.25d0)
     934              : 
     935            0 :                if (.not. skip_partials) then
     936            0 :                   dlnT_dL = 0; dlnT_dlnR = 0; dlnT_dlnM = 0; dlnT_dlnkap = 0
     937            0 :                   dlnP_dL = 0; dlnP_dlnR = 0; dlnP_dlnM = 0; dlnP_dlnkap = 0
     938              :                end if
     939              : 
     940              :             case default
     941              : 
     942              :                   ! Everything else -- the 'non-trivial atmospheres' ---
     943              :                   ! gets passed to atm_support
     944              : 
     945              :                if (.false. .and. 1 == s% solver_test_partials_k .and. &
     946              :                      s% solver_iter == s% solver_test_partials_iter_number) then
     947              :                   star_debugging_atm_flag = .true.
     948              :                end if
     949              : 
     950              :                call get_atm_PT( &
     951              :                   s, tau_surf, L_surf, R_surf, s% m(1), s% cgrav(1), skip_partials, &
     952              :                   Teff, lnT_surf, dlnT_dL, dlnT_dlnR, dlnT_dlnM, dlnT_dlnkap, &
     953              :                   lnP_surf, dlnP_dL, dlnP_dlnR, dlnP_dlnM, dlnP_dlnkap, &
     954           44 :                   ierr)
     955           44 :                if (ierr /= 0) then
     956            0 :                   if (s% report_ierr) then
     957            0 :                      write(*,1) 'tau_surf', tau_surf
     958            0 :                      write(*,1) 'L_surf', L_surf
     959            0 :                      write(*,1) 'R_surf', R_surf
     960            0 :                      write(*,1) 'Teff', Teff
     961            0 :                      write(*,1) 's% m(1)', s% m(1)
     962            0 :                      write(*,1) 's% cgrav(1)', s% cgrav(1)
     963            0 :                      write(*,*) 'failed in get_atm_PT'
     964              :                   end if
     965            0 :                   return
     966              :                end if
     967              : 
     968              :                if (.false. .and. 1 == s% solver_test_partials_k .and. &
     969           44 :                      s% solver_iter == s% solver_test_partials_iter_number) then
     970              :                   s% solver_test_partials_val = atm_test_partials_val
     971              :                   s% solver_test_partials_dval_dx = atm_test_partials_dval_dx
     972              :                end if
     973              :             end select
     974              :          end if
     975              : 
     976              :          ! if using fixed surface, calculate Pextra.
     977              :          if (s% atm_option == 'fixed_Tsurf' .or. s% atm_option == 'fixed_Psurf_and_Tsurf' &
     978           44 :             .or. s% atm_option == 'fixed_Psurf' .or. s% atm_option == 'fixed_Teff') then
     979              :             ! add extra pressure for fixed atmosphere options
     980            0 :             if (s% Pextra_factor /= 0._dp) then
     981            0 :                P_surf_atm = exp(lnP_surf)
     982            0 :                Pextra = s% Pextra_factor*(kap_surf/tau_surf)*(L_surf/M_surf)/(6._dp*pi*clight*s% cgrav(1))
     983            0 :                P_surf = P_surf_atm + Pextra
     984            0 :                if (P_surf < 1E-50_dp) then
     985            0 :                   lnP_surf = -50*ln10
     986            0 :                   if (.not. skip_partials) then
     987            0 :                      dlnP_dL = 0._dp
     988            0 :                      dlnP_dlnR = 0._dp
     989            0 :                      dlnP_dlnM = 0._dp
     990            0 :                      dlnP_dlnkap = 0._dp
     991              :                   end if
     992              :                else
     993            0 :                   lnP_surf = log(P_surf)
     994            0 :                   if (.not. skip_partials) then
     995            0 :                      dlnP_dL = dlnP_dL*P_surf_atm/P_surf
     996            0 :                      dlnP_dlnR = dlnP_dlnR*P_surf_atm/P_surf
     997            0 :                      dlnP_dlnM = dlnP_dlnM*P_surf_atm/P_surf
     998            0 :                      dlnP_dlnkap = dlnP_dlnkap*P_surf_atm/P_surf
     999              :                   end if
    1000              :                end if
    1001              :             end if
    1002              :          end if
    1003              : 
    1004              :          ! Check outputs
    1005              : 
    1006           44 :          if (is_bad(lnT_surf) .or. is_bad(lnP_surf)) then
    1007            0 :             if (len_trim(s% retry_message) == 0) s% retry_message = 'bad logT surf or logP surf'
    1008            0 :             ierr = -1
    1009            0 :             write(*,1) 'bad outputs in get_surf_PT'
    1010            0 :             write(*,1) 'lnT_surf', lnT_surf
    1011            0 :             write(*,1) 'lnP_surf', lnP_surf
    1012            0 :             write(*,*) 'atm_option = ', trim(s% atm_option)
    1013            0 :             if (s% stop_for_bad_nums) call mesa_error(__FILE__,__LINE__,'get PT surf')
    1014              :          end if
    1015              : 
    1016              :          return
    1017              : 
    1018           44 :       end subroutine get_surf_PT
    1019              : 
    1020              : 
    1021           44 :       subroutine set_grads(s, ierr)
    1022           44 :          use chem_def, only: chem_isos
    1023              :          use star_utils, only: smooth, safe_div_val
    1024              :          type (star_info), pointer :: s
    1025              :          integer, intent(out) :: ierr
    1026              : 
    1027              :          integer :: k, nz, j, cid, max_cid
    1028           44 :          real(dp) :: val, max_val, A, Z
    1029           44 :          real(dp), pointer, dimension(:) :: dlnP, dlnd, dlnT
    1030              : 
    1031              :          include 'formats'
    1032              : 
    1033           44 :          ierr = 0
    1034           44 :          nz = s% nz
    1035           44 :          call do_alloc(ierr)
    1036           44 :          if (ierr /= 0) return
    1037              : 
    1038        53820 :          do k = 2, nz
    1039        53776 :             dlnP(k) = s% lnPeos(k-1) - s% lnPeos(k)
    1040        53776 :             dlnd(k) = s% lnd(k-1) - s% lnd(k)
    1041        53820 :             dlnT(k) = s% lnT(k-1) - s% lnT(k)
    1042              :          end do
    1043           44 :          dlnP(1) = dlnP(2)
    1044           44 :          dlnd(1) = dlnd(2)
    1045           44 :          dlnT(1) = dlnT(2)
    1046              : 
    1047           44 :          call smooth(dlnP,nz)
    1048           44 :          call smooth(dlnd,nz)
    1049           44 :          call smooth(dlnT,nz)
    1050              : 
    1051           44 :          s% grad_density(1) = 0
    1052           44 :          s% grad_temperature(1) = 0
    1053        53820 :          do k = 2, nz
    1054        53820 :             if (dlnP(k) >= 0) then
    1055            2 :                s% grad_density(k) = 0
    1056            2 :                s% grad_temperature(k) = 0
    1057              :             else
    1058        53774 :                s% grad_density(k) = safe_div_val(s, dlnd(k), dlnP(k))
    1059        53774 :                s% grad_temperature(k) = safe_div_val(s, dlnT(k), dlnP(k))
    1060              :             end if
    1061              :          end do
    1062              : 
    1063           44 :          call smooth(s% grad_density,nz)
    1064           44 :          call smooth(s% grad_temperature,nz)
    1065              : 
    1066              :          ! this will compute the values of s% smoothed_brunt_B
    1067           44 :          if (s% calculate_Brunt_B) then
    1068        53864 :             do k=1,nz
    1069        53864 :                s% smoothed_brunt_B(k) = s% unsmoothed_brunt_B(k)
    1070              :             end do
    1071           44 :             call compute_smoothed_brunt_B
    1072              :          else
    1073            0 :             s% smoothed_brunt_B(:) = 0d0
    1074              :          end if
    1075           44 :          if (s% use_Ledoux_criterion .and. s% calculate_Brunt_B) then
    1076            0 :             do k=1,nz
    1077            0 :                s% gradL_composition_term(k) = s% smoothed_brunt_B(k)
    1078              :             end do
    1079              :          else
    1080        53864 :             do k=1,nz
    1081        53864 :                s% gradL_composition_term(k) = 0d0
    1082              :             end do
    1083              :          end if
    1084              : 
    1085              :          call dealloc
    1086              : 
    1087        53688 :          do k=3,nz-2
    1088        53644 :             max_cid = 0
    1089        53644 :             max_val = -1d99
    1090       482796 :             do j=1,s% species
    1091       429152 :                cid = s% chem_id(j)
    1092       429152 :                A = dble(chem_isos% Z_plus_N(cid))
    1093       429152 :                Z = dble(chem_isos% Z(cid))
    1094       429152 :                val = (s% xa(j,k-2) + s% xa(j,k-1) - s% xa(j,k) - s% xa(j,k+1))*(1d0 + Z)/A
    1095       482796 :                if (val > max_val) then
    1096        66337 :                   max_val = val
    1097        66337 :                   max_cid = cid
    1098              :                end if
    1099              :             end do
    1100        53688 :             s% dominant_iso_for_thermohaline(k) = max_cid
    1101              :          end do
    1102              :          s% dominant_iso_for_thermohaline(1:2) = &
    1103          132 :             s% dominant_iso_for_thermohaline(3)
    1104              :          s% dominant_iso_for_thermohaline(nz-1:nz) = &
    1105          132 :             s% dominant_iso_for_thermohaline(nz-2)
    1106              : 
    1107              : 
    1108              :          contains
    1109              : 
    1110          132 :          subroutine compute_smoothed_brunt_B
    1111           44 :             use star_utils, only: weighed_smoothing, threshold_smoothing
    1112              :             logical, parameter :: preserve_sign = .false.
    1113              :             real(dp), pointer, dimension(:) :: work
    1114              :             include 'formats'
    1115           44 :             ierr = 0
    1116           44 :             work => dlnd
    1117           44 :             if (s% num_cells_for_smooth_gradL_composition_term <= 0) return
    1118              :             call threshold_smoothing( &
    1119              :                s% smoothed_brunt_B, s% threshold_for_smooth_gradL_composition_term, s% nz, &
    1120           44 :                s% num_cells_for_smooth_gradL_composition_term, preserve_sign, work)
    1121           44 :          end subroutine compute_smoothed_brunt_B
    1122              : 
    1123           44 :          subroutine do_alloc(ierr)
    1124              :             integer, intent(out) :: ierr
    1125           44 :             call do_work_arrays(.true.,ierr)
    1126           44 :          end subroutine do_alloc
    1127              : 
    1128           44 :          subroutine dealloc
    1129           44 :             call do_work_arrays(.false.,ierr)
    1130              :          end subroutine dealloc
    1131              : 
    1132           88 :          subroutine do_work_arrays(alloc_flag, ierr)
    1133              :             use alloc, only: work_array
    1134              :             logical, intent(in) :: alloc_flag
    1135              :             integer, intent(out) :: ierr
    1136              :             logical, parameter :: crit = .false.
    1137              :             ierr = 0
    1138              :             call work_array(s, alloc_flag, crit, &
    1139           88 :                dlnP, nz, nz_alloc_extra, 'mlt', ierr)
    1140           88 :             if (ierr /= 0) return
    1141              :             call work_array(s, alloc_flag, crit, &
    1142           88 :                dlnd, nz, nz_alloc_extra, 'mlt', ierr)
    1143           88 :             if (ierr /= 0) return
    1144              :             call work_array(s, alloc_flag, crit, &
    1145           88 :                dlnT, nz, nz_alloc_extra, 'mlt', ierr)
    1146           88 :             if (ierr /= 0) return
    1147           88 :          end subroutine do_work_arrays
    1148              : 
    1149              :       end subroutine set_grads
    1150              : 
    1151              :       end module hydro_vars
        

Generated by: LCOV version 2.0-1