LCOV - code coverage report
Current view: top level - star/private - reconstructed_face_support.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 6.2 % 227 14
Test Date: 2026-08-20 21:51:39 Functions: 6.7 % 15 1

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2025  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 reconstructed_face_support
      21              : 
      22              :   use star_private_def
      23              :   use const_def, only: dp, ln10, pi4, clight, crad
      24              :   use auto_diff
      25              :   use kap_support, only: get_kap
      26              : 
      27              :   implicit none
      28              : 
      29              :   private
      30              :   public :: get_reconstructed_face_state_ad
      31              :   public :: get_reconstructed_face_eos_kap_ad
      32              :   public :: get_reconstructed_scale_height_ad
      33              : 
      34              : contains
      35              : 
      36              :   ! Returns the MLT/TDC face thermodynamic state as
      37              :   ! auto_diff_real_star_order1 quantities, either from recomputed face
      38              :   ! EOS/opacity data or from the stored face quantities.
      39        79994 :   subroutine get_reconstructed_face_state_ad( &
      40              :        s, k, T_face, rho_face, P_face, energy_face, Cp_face, ChiRho_face, ChiT_face, grada_face, &
      41              :        opacity_face, scale_height_face, gradr_face, ierr)
      42              :     use star_utils, only: get_T_face, get_Peos_face, get_e_face, get_kap_face, get_rho_face, &
      43              :        get_ChiRho_face, get_ChiT_face, get_Cp_face, get_grada_face, get_scale_height_face, get_gradr_face
      44              : 
      45              :     type(star_info), pointer :: s
      46              :     integer, intent(in) :: k
      47              :     type(auto_diff_real_star_order1), intent(out) :: &
      48              :        T_face, rho_face, P_face, energy_face, Cp_face, ChiRho_face, ChiT_face, grada_face, &
      49              :        opacity_face, scale_height_face, gradr_face
      50              :     integer, intent(out) :: ierr
      51              : 
      52        79994 :     ierr = 0
      53        79994 :     if (s%use_face_reconstruction) then
      54            0 :        call ensure_reconstructed_face_state_ad(s, k, ierr)
      55            0 :        if (ierr /= 0) return
      56            0 :        T_face = s%reconstructed_T_face_ad(k)
      57            0 :        rho_face = s%reconstructed_rho_face_ad(k)
      58            0 :        P_face = s%reconstructed_P_face_ad(k)
      59            0 :        energy_face = s%reconstructed_energy_face_ad(k)
      60            0 :        Cp_face = s%reconstructed_Cp_face_ad(k)
      61            0 :        ChiRho_face = s%reconstructed_ChiRho_face_ad(k)
      62            0 :        ChiT_face = s%reconstructed_ChiT_face_ad(k)
      63            0 :        grada_face = s%reconstructed_grada_face_ad(k)
      64            0 :        opacity_face = s%reconstructed_opacity_face_ad(k)
      65            0 :        scale_height_face = s%reconstructed_scale_height_face_ad(k)
      66            0 :        gradr_face = s%reconstructed_gradr_face_ad(k)
      67              :     else
      68        79994 :        T_face = get_T_face(s, k)
      69        79994 :        P_face = get_Peos_face(s, k)
      70        79994 :        energy_face = get_e_face(s, k)
      71        79994 :        opacity_face = get_kap_face(s, k)
      72        79994 :        rho_face = get_rho_face(s, k)
      73        79994 :        ChiRho_face = get_ChiRho_face(s, k)
      74        79994 :        ChiT_face = get_ChiT_face(s, k)
      75        79994 :        Cp_face = get_Cp_face(s, k)
      76        79994 :        grada_face = get_grada_face(s, k)
      77        79994 :        scale_height_face = get_scale_height_face(s, k)
      78        79994 :        gradr_face = get_gradr_face(s, k)
      79              :     end if
      80              :   end subroutine get_reconstructed_face_state_ad
      81              : 
      82              : 
      83              :   ! Ensures that the recomputed MLT and TDC face thermodynamic quantities have
      84              :   ! been assembled and cached for face k.
      85            0 :   subroutine ensure_reconstructed_face_state_ad(s, k, ierr)
      86              :     type(star_info), pointer :: s
      87              :     integer, intent(in) :: k
      88              :     integer, intent(out) :: ierr
      89              : 
      90              :     type(auto_diff_real_star_order1) :: T_face, rho_face, P_face, energy_face, Cp_face
      91              :     type(auto_diff_real_star_order1) :: ChiRho_face, ChiT_face, grada_face, opacity_face
      92              :     type(auto_diff_real_star_order1) :: scale_height_face, gradr_face
      93              :     real(dp) :: csound_face
      94              : 
      95            0 :     ierr = 0
      96            0 :     if (s%reconstructed_face_state_valid(k)) return
      97              : 
      98              :     call build_reconstructed_face_state_ad( &
      99              :        s, k, T_face, rho_face, P_face, energy_face, Cp_face, ChiRho_face, ChiT_face, grada_face, &
     100            0 :        opacity_face, scale_height_face, gradr_face, csound_face, ierr)
     101            0 :     if (ierr /= 0) return
     102              : 
     103            0 :     s%reconstructed_T_face_ad(k) = T_face
     104            0 :     s%reconstructed_rho_face_ad(k) = rho_face
     105            0 :     s%reconstructed_P_face_ad(k) = P_face
     106            0 :     s%reconstructed_energy_face_ad(k) = energy_face
     107            0 :     s%reconstructed_Cp_face_ad(k) = Cp_face
     108            0 :     s%reconstructed_ChiRho_face_ad(k) = ChiRho_face
     109            0 :     s%reconstructed_ChiT_face_ad(k) = ChiT_face
     110            0 :     s%reconstructed_grada_face_ad(k) = grada_face
     111            0 :     s%reconstructed_opacity_face_ad(k) = opacity_face
     112            0 :     s%reconstructed_scale_height_face_ad(k) = scale_height_face
     113            0 :     s%reconstructed_gradr_face_ad(k) = gradr_face
     114            0 :     s%reconstructed_csound_face(k) = csound_face
     115            0 :     s%reconstructed_face_state_valid(k) = .true.
     116              :   end subroutine ensure_reconstructed_face_state_ad
     117              : 
     118              :   ! Reconstructs the face composition from either the current or the
     119              :   ! start-of-step composition, renormalizes xa_face, and derives zbar_face.
     120            0 :   subroutine get_face_composition(s, k, use_starting_comp, zbar_face, xa_face, ierr)
     121              :     use chem_lib, only: basic_composition_info
     122              :     use star_utils, only: get_face_weights
     123              : 
     124              :     type(star_info), pointer :: s
     125              :     integer, intent(in) :: k
     126              :     logical, intent(in) :: use_starting_comp
     127              :     real(dp), intent(out) :: zbar_face
     128              :     real(dp), intent(out) :: xa_face(:)
     129              :     integer, intent(out) :: ierr
     130              : 
     131              :     real(dp) :: alfa, beta, sum_xa
     132              :     real(dp) :: xh, xhe, z, abar, z2bar, z53bar, ye, mass_correction, sumx
     133              : 
     134            0 :     ierr = 0
     135            0 :     if (k == 1) then
     136            0 :        alfa = 1d0
     137            0 :        beta = 0d0
     138              :     else
     139            0 :        call get_face_weights(s, k, alfa, beta)
     140              :     end if
     141              : 
     142            0 :     if (use_starting_comp) then
     143            0 :        xa_face(1:s%species) = alfa*s%xa_start(1:s%species, k)
     144            0 :        if (k > 1) xa_face(1:s%species) = xa_face(1:s%species) + beta*s%xa_start(1:s%species, k-1)
     145              :     else
     146            0 :        xa_face(1:s%species) = alfa*s%xa(1:s%species, k)
     147            0 :        if (k > 1) xa_face(1:s%species) = xa_face(1:s%species) + beta*s%xa(1:s%species, k-1)
     148              :     end if
     149              : 
     150            0 :     sum_xa = sum(xa_face)
     151            0 :     if (sum_xa <= 0d0) then
     152            0 :       ierr = -1
     153            0 :       if (s%report_ierr) then
     154            0 :          !$OMP critical (reconstructed_face_report_ierr)
     155            0 :          write(*,*) 'get_face_composition: sum_xa <= 0 for k', k
     156              :          !$OMP end critical (reconstructed_face_report_ierr)
     157              :       end if
     158            0 :       return
     159              :     end if
     160            0 :     xa_face = xa_face/sum_xa
     161              :     call basic_composition_info( &
     162              :        s%species, s%chem_id, xa_face, xh, xhe, z, abar, zbar_face, &
     163            0 :        z2bar, z53bar, ye, mass_correction, sumx)
     164              :   end subroutine get_face_composition
     165              : 
     166              : 
     167              :   ! Builds the recomputed face EOS input state by wrapping T and rho to the
     168              :   ! face, reconstructing the face composition, and evaluating the EOS there.
     169            0 :   subroutine get_face_eos_inputs( &
     170              :        s, k, T_face, rho_face, eos_res, d_dlnd, d_dlnT, ierr)
     171              :     use eos_support, only: get_eos
     172              :     use eos_def, only: num_eos_basic_results, num_eos_d_dxa_results
     173              :     use star_utils, only: get_rho_face, get_T_face
     174              : 
     175              :     type(star_info), pointer :: s
     176              :     integer, intent(in) :: k
     177              :     type(auto_diff_real_star_order1), intent(out) :: T_face, rho_face
     178              :     real(dp), intent(out) :: eos_res(num_eos_basic_results), d_dlnd(num_eos_basic_results), d_dlnT(num_eos_basic_results)
     179              :     integer, intent(out) :: ierr
     180              : 
     181              :     real(dp) :: log10_T, log10_rho, zbar_face
     182            0 :     real(dp) :: eos_xa_face(s%species)
     183            0 :     real(dp) :: d_dxa(num_eos_d_dxa_results, s%species)
     184              : 
     185            0 :     ierr = 0
     186            0 :     T_face = get_T_face(s, k)
     187            0 :     rho_face = get_rho_face(s, k)
     188            0 :     if (T_face%val <= 0d0 .or. rho_face%val <= 0d0) then
     189            0 :        ierr = -1
     190            0 :        if (s%report_ierr) then
     191            0 :           !$OMP critical (reconstructed_face_report_ierr)
     192            0 :           write(*,*) 'get_face_eos_inputs: bad face T or rho for k', k, T_face%val, rho_face%val
     193              :           !$OMP end critical (reconstructed_face_report_ierr)
     194              :        end if
     195            0 :        return
     196              :     end if
     197              : 
     198            0 :     call get_face_composition(s, k, .false., zbar_face, eos_xa_face, ierr)
     199            0 :     if (ierr /= 0) return
     200              : 
     201            0 :     log10_T = log10(T_face%val)
     202            0 :     log10_rho = log10(rho_face%val)
     203              : 
     204              :     call get_eos( &
     205              :        s, k, eos_xa_face, rho_face%val, log10_rho, T_face%val, log10_T, &
     206            0 :        eos_res, d_dlnd, d_dlnT, d_dxa, ierr)
     207            0 :     if (ierr /= 0) then
     208            0 :        if (s%report_ierr) call write_face_eos_call_info(s, k, T_face, rho_face, zbar_face, eos_xa_face)
     209            0 :        return
     210              :     end if
     211              :   end subroutine get_face_eos_inputs
     212              : 
     213              : 
     214              :   ! Interpolates extra_opacity_factor to the face and applies the existing
     215              :   ! logT taper used to turn that factor on and off.
     216            0 :   subroutine get_face_opacity_factor(s, k, log10_T, opacity_factor_face)
     217              :     use star_utils, only: get_face_weights
     218              : 
     219              :     type(star_info), pointer :: s
     220              :     integer, intent(in) :: k
     221              :     real(dp), intent(in) :: log10_T
     222              :     real(dp), intent(out) :: opacity_factor_face
     223              : 
     224              :     real(dp) :: alfa, beta
     225              : 
     226            0 :     if (k == 1) then
     227            0 :        alfa = 1d0
     228            0 :        beta = 0d0
     229              :     else
     230            0 :        call get_face_weights(s, k, alfa, beta)
     231              :     end if
     232              : 
     233            0 :     opacity_factor_face = alfa*s%extra_opacity_factor(k)
     234            0 :     if (k > 1) opacity_factor_face = opacity_factor_face + beta*s%extra_opacity_factor(k-1)
     235            0 :     if (s%min_logT_for_opacity_factor_off > 0) then
     236            0 :        if (log10_T >= s%max_logT_for_opacity_factor_off .or. &
     237              :              log10_T <= s%min_logT_for_opacity_factor_off) then
     238            0 :           opacity_factor_face = 1d0
     239            0 :        else if (log10_T > s%max_logT_for_opacity_factor_on) then
     240              :           opacity_factor_face = 1d0 + (opacity_factor_face - 1d0)* &
     241              :              (log10_T - s%max_logT_for_opacity_factor_off)/ &
     242            0 :              (s%max_logT_for_opacity_factor_on - s%max_logT_for_opacity_factor_off)
     243            0 :        else if (log10_T < s%min_logT_for_opacity_factor_on) then
     244              :           opacity_factor_face = 1d0 + (opacity_factor_face - 1d0)* &
     245              :              (log10_T - s%min_logT_for_opacity_factor_off)/ &
     246            0 :              (s%min_logT_for_opacity_factor_on - s%min_logT_for_opacity_factor_off)
     247              :        end if
     248              :     end if
     249            0 :   end subroutine get_face_opacity_factor
     250              : 
     251              : 
     252              :   ! Returns the cached or newly built face EOS and opacity state as
     253              :   ! auto_diff_real_star_order1 quantities for the MLT/TDC solve,
     254              :   ! instead of using the stored face quantities.
     255            0 :   subroutine get_reconstructed_face_eos_kap_ad( &
     256              :        s, k, T_face, rho_face, P_face, Cp_face, ChiRho_face, ChiT_face, grada_face, opacity_face, ierr)
     257              :     type(star_info), pointer :: s
     258              :     integer, intent(in) :: k
     259              :     type(auto_diff_real_star_order1), intent(out) :: T_face, rho_face, P_face, Cp_face, ChiRho_face, ChiT_face, grada_face, opacity_face
     260              :     integer, intent(out) :: ierr
     261              : 
     262              :     ierr = 0
     263            0 :     call ensure_reconstructed_face_state_ad(s, k, ierr)
     264            0 :     if (ierr /= 0) return
     265              : 
     266            0 :     T_face = s%reconstructed_T_face_ad(k)
     267            0 :     rho_face = s%reconstructed_rho_face_ad(k)
     268            0 :     P_face = s%reconstructed_P_face_ad(k)
     269            0 :     Cp_face = s%reconstructed_Cp_face_ad(k)
     270            0 :     ChiRho_face = s%reconstructed_ChiRho_face_ad(k)
     271            0 :     ChiT_face = s%reconstructed_ChiT_face_ad(k)
     272            0 :     grada_face = s%reconstructed_grada_face_ad(k)
     273            0 :     opacity_face = s%reconstructed_opacity_face_ad(k)
     274              :   end subroutine get_reconstructed_face_eos_kap_ad
     275              : 
     276              : 
     277              :   ! Builds the full set of recomputed face thermodynamic quantities for the
     278              :   ! MLT and TDC solve from one EOS call and one opacity call at face k.
     279            0 :   subroutine build_reconstructed_face_state_ad( &
     280              :        s, k, T_face, rho_face, P_face, energy_face, Cp_face, ChiRho_face, ChiT_face, grada_face, &
     281              :        opacity_face, scale_height_face, gradr_face, csound_face, ierr)
     282              :     use eos_def, only: num_eos_basic_results, i_lnPgas, i_lnE, i_grad_ad, i_gamma1, i_Cp, i_chiRho, i_chiT, i_eta, i_lnfree_e
     283              :     use kap_def, only: num_kap_fracs
     284              : 
     285              :     type(star_info), pointer :: s
     286              :     integer, intent(in) :: k
     287              :     type(auto_diff_real_star_order1), intent(out) :: &
     288              :        T_face, rho_face, P_face, energy_face, Cp_face, ChiRho_face, ChiT_face, grada_face, &
     289              :        opacity_face, scale_height_face, gradr_face
     290              :     real(dp), intent(out) :: csound_face
     291              :     integer, intent(out) :: ierr
     292              : 
     293              :     real(dp) :: log10_T, log10_rho, kap_zbar_face, opacity_factor_face, csound2
     294              :     real(dp) :: eos_res(num_eos_basic_results), d_dlnd(num_eos_basic_results), d_dlnT(num_eos_basic_results)
     295              :     real(dp) :: dlnT_face(auto_diff_star_num_vars), dlnd_face(auto_diff_star_num_vars)
     296              :     real(dp) :: kap, dlnkap_dlnd, dlnkap_dlnT
     297            0 :     real(dp) :: kap_fracs(num_kap_fracs), kap_xa_face(s%species)
     298              :     type(auto_diff_real_star_order1) :: Pgas_face, gamma1_face, mlt_Pturb_ad, alpha
     299              : 
     300              :     ierr = 0
     301              :     call get_face_eos_inputs( &
     302            0 :        s, k, T_face, rho_face, eos_res, d_dlnd, d_dlnT, ierr)
     303            0 :     if (ierr /= 0) return
     304            0 :     log10_T = log10(T_face%val)
     305            0 :     log10_rho = log10(rho_face%val)
     306            0 :     call set_face_log_partials(T_face, rho_face, dlnT_face, dlnd_face)
     307              : 
     308            0 :     call set_face_ad_from_log(eos_res(i_lnPgas), d_dlnd(i_lnPgas), d_dlnT(i_lnPgas), dlnd_face, dlnT_face, Pgas_face)
     309            0 :     P_face = Pgas_face + crad*pow4(T_face)/3d0
     310            0 :     call set_face_ad_from_log(eos_res(i_lnE), d_dlnd(i_lnE), d_dlnT(i_lnE), dlnd_face, dlnT_face, energy_face)
     311            0 :     call set_face_ad_from_value(eos_res(i_Cp), d_dlnd(i_Cp), d_dlnT(i_Cp), dlnd_face, dlnT_face, Cp_face)
     312            0 :     call set_face_ad_from_value(eos_res(i_chiRho), d_dlnd(i_chiRho), d_dlnT(i_chiRho), dlnd_face, dlnT_face, ChiRho_face)
     313            0 :     call set_face_ad_from_value(eos_res(i_chiT), d_dlnd(i_chiT), d_dlnT(i_chiT), dlnd_face, dlnT_face, ChiT_face)
     314            0 :     call set_face_ad_from_value(eos_res(i_grad_ad), d_dlnd(i_grad_ad), d_dlnT(i_grad_ad), dlnd_face, dlnT_face, grada_face)
     315            0 :     call set_face_ad_from_value(eos_res(i_gamma1), d_dlnd(i_gamma1), d_dlnT(i_gamma1), dlnd_face, dlnT_face, gamma1_face)
     316            0 :     csound2 = gamma1_face%val*P_face%val/rho_face%val
     317            0 :     if (is_bad_num(csound2) .or. csound2 <= 0d0) then
     318            0 :        ierr = -1
     319            0 :        if (s%report_ierr) then
     320            0 :           !$OMP critical (reconstructed_face_report_ierr)
     321            0 :           write(*,*) 'build_reconstructed_face_state_ad: bad face csound squared for k', k, csound2
     322              :           !$OMP end critical (reconstructed_face_report_ierr)
     323              :        end if
     324            0 :        return
     325              :     end if
     326            0 :     csound_face = sqrt(csound2)
     327              : 
     328            0 :     call get_face_composition(s, k, s% use_starting_composition_for_kap, kap_zbar_face, kap_xa_face, ierr)
     329            0 :     if (ierr /= 0) return
     330            0 :     call get_face_opacity_factor(s, k, log10_T, opacity_factor_face)
     331              : 
     332              :     call get_kap( &
     333              :        s, k, kap_zbar_face, kap_xa_face, log10_rho, log10_T, &
     334              :        eos_res(i_lnfree_e), d_dlnd(i_lnfree_e), d_dlnT(i_lnfree_e), &
     335              :        eos_res(i_eta), d_dlnd(i_eta), d_dlnT(i_eta), &
     336            0 :        kap_fracs, kap, dlnkap_dlnd, dlnkap_dlnT, ierr)
     337            0 :     if (ierr /= 0) then
     338            0 :        if (s%report_ierr) call write_face_kap_call_info( &
     339            0 :           s, k, T_face, rho_face, kap_zbar_face, kap_xa_face, opacity_factor_face)
     340            0 :        return
     341              :     end if
     342            0 :     if (is_bad_num(kap) .or. kap <= 0d0) then
     343            0 :        ierr = -1
     344            0 :        if (s%report_ierr) then
     345            0 :           !$OMP critical (reconstructed_face_report_ierr)
     346            0 :           write(*,*) 'get_reconstructed_face_eos_kap_ad: bad face opacity for k', k, kap
     347              :           !$OMP end critical (reconstructed_face_report_ierr)
     348            0 :           call write_face_kap_call_info(s, k, T_face, rho_face, kap_zbar_face, kap_xa_face, opacity_factor_face)
     349              :        end if
     350            0 :        return
     351              :     end if
     352              : 
     353            0 :     kap = kap*opacity_factor_face
     354            0 :     if (s%opacity_max > 0d0 .and. kap > s%opacity_max) then
     355            0 :        kap = s%opacity_max
     356            0 :        dlnkap_dlnd = 0d0
     357            0 :        dlnkap_dlnT = 0d0
     358              :     end if
     359            0 :     if (s%opacity_min > 0d0 .and. kap < s%opacity_min) then
     360            0 :        kap = s%opacity_min
     361            0 :        dlnkap_dlnd = 0d0
     362            0 :        dlnkap_dlnT = 0d0
     363              :     end if
     364            0 :     call set_face_ad_from_value(kap, kap*dlnkap_dlnd, kap*dlnkap_dlnT, dlnd_face, dlnT_face, opacity_face)
     365              : 
     366              :     if (s% have_mlt_vc .and. s% okay_to_set_mlt_vc .and. s% include_mlt_Pturb_in_thermodynamic_gradients &
     367            0 :        .and. s% mlt_Pturb_factor > 0d0 .and. k > 1) then
     368            0 :        mlt_Pturb_ad = s% mlt_Pturb_factor*pow2(s% mlt_vc_old(k))*rho_face/3d0
     369            0 :        alpha = mlt_Pturb_ad/(P_face*gamma1_face)
     370            0 :        grada_face = grada_face*(P_face + mlt_Pturb_ad)/(P_face*(1d0 + alpha))
     371              :     end if
     372              : 
     373            0 :     call set_scale_height_from_face_state(s, k, P_face, rho_face, scale_height_face)
     374            0 :     call set_gradr_from_face_state(s, k, P_face, opacity_face, T_face, gradr_face)
     375              :   end subroutine build_reconstructed_face_state_ad
     376              : 
     377              : 
     378              :   ! Returns the cached or newly built face pressure scale height as an
     379              :   ! auto_diff_real_star_order1 quantity from the face EOS state.
     380            0 :   subroutine get_reconstructed_scale_height_ad(s, k, scale_height_face, ierr)
     381              :     type(star_info), pointer :: s
     382              :     integer, intent(in) :: k
     383              :     type(auto_diff_real_star_order1), intent(out) :: scale_height_face
     384              :     integer, intent(out) :: ierr
     385              : 
     386              :     ierr = 0
     387            0 :     call ensure_reconstructed_face_state_ad(s, k, ierr)
     388            0 :     if (ierr /= 0) return
     389            0 :     scale_height_face = s%reconstructed_scale_height_face_ad(k)
     390              :   end subroutine get_reconstructed_scale_height_ad
     391              : 
     392              : 
     393            0 :   subroutine set_scale_height_from_face_state(s, k, P_face, rho_face, scale_height_face)
     394              :     use auto_diff_support, only: wrap_r_00
     395              : 
     396              :     type(star_info), pointer :: s
     397              :     integer, intent(in) :: k
     398              :     type(auto_diff_real_star_order1), intent(in) :: P_face, rho_face
     399              :     type(auto_diff_real_star_order1), intent(out) :: scale_height_face
     400              : 
     401              :     real(dp) :: G
     402              :     type(auto_diff_real_star_order1) :: grav, scale_height2
     403              : 
     404            0 :     G = s%cgrav(k)
     405            0 :     grav = G*s%m_grav(k)/pow2(wrap_r_00(s,k))
     406            0 :     scale_height_face = P_face/(grav*rho_face)
     407            0 :     if (s%alt_scale_height_flag) then
     408            0 :        scale_height2 = sqrt(P_face/G)/rho_face
     409            0 :        if (scale_height2 < scale_height_face) scale_height_face = scale_height2
     410              :     end if
     411            0 :   end subroutine set_scale_height_from_face_state
     412              : 
     413              : 
     414            0 :   subroutine set_gradr_from_face_state(s, k, P_face, opacity_face, T_face, gradr_face)
     415              :     use auto_diff_support, only: wrap_L_00
     416              : 
     417              :     type(star_info), pointer :: s
     418              :     integer, intent(in) :: k
     419              :     type(auto_diff_real_star_order1), intent(in) :: P_face, opacity_face, T_face
     420              :     type(auto_diff_real_star_order1), intent(out) :: gradr_face
     421              : 
     422              :     real(dp) :: L_theta
     423              :     type(auto_diff_real_star_order1) :: L_face, Pr_face
     424              : 
     425            0 :     if (s%include_mlt_in_velocity_time_centering) then
     426              :        if (s%using_velocity_time_centering .and. &
     427            0 :              s%include_L_in_velocity_time_centering .and. &
     428              :              s%lnT(k) <= s%max_logT_for_include_P_and_L_in_velocity_time_centering*ln10) then
     429            0 :           L_theta = s%L_theta_for_velocity_time_centering
     430              :        else
     431            0 :           L_theta = 1d0
     432              :        end if
     433            0 :        L_face = L_theta*wrap_L_00(s, k) + (1d0 - L_theta)*s%L_start(k)
     434              :     else
     435            0 :        L_face = wrap_L_00(s, k)
     436              :     end if
     437              : 
     438            0 :     Pr_face = crad*pow4(T_face)/3d0
     439            0 :     gradr_face = P_face*opacity_face*L_face/(4d0*pi4*clight*s%m_grav(k)*s%cgrav(k)*Pr_face)
     440            0 :   end subroutine set_gradr_from_face_state
     441              : 
     442              :   ! Precomputes dlnT_face and dlnd_face for converting scalar d/dlnT and
     443              :   ! d/dlnd microphysics partials into star-order1 autodiff derivatives.
     444            0 :   subroutine set_face_log_partials(T_face, rho_face, dlnT_face, dlnd_face)
     445              :     type(auto_diff_real_star_order1), intent(in) :: T_face, rho_face
     446              :     real(dp), intent(out) :: dlnT_face(auto_diff_star_num_vars), dlnd_face(auto_diff_star_num_vars)
     447              : 
     448            0 :     dlnT_face = T_face%d1Array/T_face%val
     449            0 :     dlnd_face = rho_face%d1Array/rho_face%val
     450            0 :   end subroutine set_face_log_partials
     451              : 
     452              : 
     453              :   ! Converts a scalar value with d/dlnd and d/dlnT partials into an
     454              :   ! auto_diff_real_star_order1 quantity using the face chain rule.
     455            0 :   subroutine set_face_ad_from_value(value, dvalue_dlnd, dvalue_dlnT, dlnd_face, dlnT_face, quantity_ad)
     456              :     real(dp), intent(in) :: value, dvalue_dlnd, dvalue_dlnT
     457              :     real(dp), intent(in) :: dlnd_face(auto_diff_star_num_vars), dlnT_face(auto_diff_star_num_vars)
     458              :     type(auto_diff_real_star_order1), intent(out) :: quantity_ad
     459              : 
     460            0 :     quantity_ad = 0d0
     461            0 :     quantity_ad%val = value
     462            0 :     quantity_ad%d1Array = dvalue_dlnd*dlnd_face + dvalue_dlnT*dlnT_face
     463            0 :   end subroutine set_face_ad_from_value
     464              : 
     465              : 
     466              :   ! Same as set_face_ad_from_value, but for a quantity returned in
     467              :   ! logarithmic form by the microphysics routine.
     468            0 :   subroutine set_face_ad_from_log(log_value, dlog_dlnd, dlog_dlnT, dlnd_face, dlnT_face, quantity_ad)
     469              :     real(dp), intent(in) :: log_value, dlog_dlnd, dlog_dlnT
     470              :     real(dp), intent(in) :: dlnd_face(auto_diff_star_num_vars), dlnT_face(auto_diff_star_num_vars)
     471              :     type(auto_diff_real_star_order1), intent(out) :: quantity_ad
     472              :     real(dp) :: value
     473              : 
     474            0 :     value = exp(log_value)
     475            0 :     call set_face_ad_from_value(value, value*dlog_dlnd, value*dlog_dlnT, dlnd_face, dlnT_face, quantity_ad)
     476            0 :   end subroutine set_face_ad_from_log
     477              : 
     478              : 
     479              :   ! Writes the recomputed face EOS inputs that were passed to get_eos.
     480            0 :   subroutine write_face_eos_call_info(s, k, T_face, rho_face, zbar_face, xa_face)
     481              :     type(star_info), pointer :: s
     482              :     integer, intent(in) :: k
     483              :     type(auto_diff_real_star_order1), intent(in) :: T_face, rho_face
     484              :     real(dp), intent(in) :: zbar_face
     485              :     real(dp), intent(in) :: xa_face(:)
     486              : 
     487              :     integer :: j
     488              :     include 'formats'
     489              : 
     490            0 :     !$OMP critical (reconstructed_face_eos_call_info)
     491            0 :     write(*,'(A)')
     492            0 :     write(*,*) 'face EOS input info for k', k
     493            0 :     write(*,1) 'T_face', T_face%val
     494            0 :     write(*,1) 'rho_face', rho_face%val
     495            0 :     write(*,1) 'log10_T_face', log10(T_face%val)
     496            0 :     write(*,1) 'log10_rho_face', log10(rho_face%val)
     497            0 :     write(*,1) 'zbar_face', zbar_face
     498            0 :     write(*,1) 'sum(xa_face)', sum(xa_face)
     499            0 :     do j = 1, s%species
     500            0 :        write(*,2) 'xa_face ' // trim(s%nameofequ(j+s%nvar_hydro)), j, xa_face(j)
     501              :     end do
     502              :     !$OMP end critical (reconstructed_face_eos_call_info)
     503            0 :   end subroutine write_face_eos_call_info
     504              : 
     505              : 
     506              :   ! Writes the recomputed face opacity inputs that were passed to get_kap.
     507            0 :   subroutine write_face_kap_call_info(s, k, T_face, rho_face, zbar_face, xa_face, opacity_factor_face)
     508              :     type(star_info), pointer :: s
     509              :     integer, intent(in) :: k
     510              :     type(auto_diff_real_star_order1), intent(in) :: T_face, rho_face
     511              :     real(dp), intent(in) :: zbar_face
     512              :     real(dp), intent(in) :: xa_face(:)
     513              :     real(dp), intent(in) :: opacity_factor_face
     514              : 
     515              :     integer :: j
     516              :     include 'formats'
     517              : 
     518            0 :     !$OMP critical (reconstructed_face_kap_call_info)
     519            0 :     write(*,'(A)')
     520            0 :     write(*,*) 'face opacity input info for k', k
     521            0 :     write(*,1) 'T_face', T_face%val
     522            0 :     write(*,1) 'rho_face', rho_face%val
     523            0 :     write(*,1) 'log10_T_face', log10(T_face%val)
     524            0 :     write(*,1) 'log10_rho_face', log10(rho_face%val)
     525            0 :     write(*,1) 'zbar_face', zbar_face
     526            0 :     write(*,1) 'opacity_factor_face', opacity_factor_face
     527            0 :     write(*,1) 'sum(xa_face)', sum(xa_face)
     528            0 :     do j = 1, s%species
     529            0 :        write(*,2) 'xa_face ' // trim(s%nameofequ(j+s%nvar_hydro)), j, xa_face(j)
     530              :     end do
     531              :     !$OMP end critical (reconstructed_face_kap_call_info)
     532            0 :   end subroutine write_face_kap_call_info
     533              : 
     534              : end module reconstructed_face_support
        

Generated by: LCOV version 2.0-1