LCOV - code coverage report
Current view: top level - turb/public - turb.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 71.9 % 57 41
Test Date: 2025-10-25 19:18:45 Functions: 50.0 % 4 2

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2019  The MESA Team
       4              : !
       5              : !   This program is free software: you can redistribute it and/or modify
       6              : !   it under the terms of the GNU Lesser General Public License
       7              : !   as published by the Free Software Foundation,
       8              : !   either version 3 of the License, or (at your option) any later version.
       9              : !
      10              : !   This program is distributed in the hope that it will be useful,
      11              : !   but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              : !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13              : !   See the GNU Lesser General Public License for more details.
      14              : !
      15              : !   You should have received a copy of the GNU Lesser General Public License
      16              : !   along with this program. If not, see <https://www.gnu.org/licenses/>.
      17              : !
      18              : ! ***********************************************************************
      19              : 
      20              : module turb
      21              :    use const_def, only: dp, pi, boltz_sigma, sqrt_2_div_3, crad, clight, no_mixing, convective_mixing, thermohaline_mixing
      22              :    use num_lib
      23              :    use utils_lib
      24              :    use auto_diff
      25              : 
      26              :    implicit none
      27              : 
      28              :    private
      29              :    public :: set_thermohaline
      30              :    public :: set_mlt
      31              :    public :: set_tdc
      32              :    public :: set_semiconvection
      33              : 
      34              :    contains
      35              : 
      36              :    !> Computes the diffusivity of thermohaline mixing when the
      37              :    !! thermal gradient is stable and the composition gradient is unstable.
      38              :    !!
      39              :    !! @param thermohaline_option A string specifying which thermohaline prescription to use.
      40              :    !! @param grada Adiabatic gradient dlnT/dlnP
      41              :    !! @param gradr Radiative temperature gradient dlnT/dlnP, equals the actual gradient because there's no convection
      42              :    !! @param T Temperature
      43              :    !! @param opacity opacity
      44              :    !! @param rho Density
      45              :    !! @param Cp Heat capacity at constant pressure
      46              :    !! @param gradL_composition_term dlnMu/dlnP where Mu is the mean molecular weight.
      47              :    !! @param iso The index of the species that drives thermohaline mixing.
      48              :    !! @param XH1 Mass fraction of H1.
      49              :    !! @param thermohaline_coeff Free parameter multiplying the thermohaline diffusivity.
      50              :    !! @param D_thrm Output, diffusivity.
      51              :    !! @param ierr Output, error index.
      52            0 :    subroutine set_thermohaline(thermohaline_option, Lambda, grada, gradr, T, opacity, rho, Cp, gradL_composition_term, &
      53              :                               iso, XH1, thermohaline_coeff, &
      54              :                               D, gradT, Y_face, conv_vel, mixing_type, ierr)
      55              :       use thermohaline
      56              :       character(len=*), intent(in) :: thermohaline_option
      57              :       type(auto_diff_real_star_order1), intent(in) :: Lambda, grada, gradr, T, opacity, rho, Cp
      58              :       real(dp), intent(in) :: gradL_composition_term, XH1, thermohaline_coeff
      59              :       integer, intent(in) :: iso
      60              : 
      61              :       type(auto_diff_real_star_order1), intent(out) :: gradT, Y_face, conv_vel, D
      62              :       integer, intent(out) :: mixing_type, ierr
      63              : 
      64              :       real(dp) :: D_thrm
      65              : 
      66              :       call get_D_thermohaline(&
      67              :          thermohaline_option, grada%val, gradr%val, T%val, opacity%val, rho%val, &
      68              :          Cp%val, gradL_composition_term, &
      69            0 :          iso, XH1, thermohaline_coeff, D_thrm, ierr)
      70              : 
      71            0 :       D = D_thrm
      72            0 :       gradT = gradr
      73            0 :       Y_face = gradT - grada
      74            0 :       conv_vel = 3d0*D/Lambda
      75            0 :       mixing_type = thermohaline_mixing
      76            0 :    end subroutine set_thermohaline
      77              : 
      78              :    !> Computes the outputs of time-dependent convection theory following the model specified in
      79              :    !! Radek Smolec's thesis [https://users.camk.edu.pl/smolec/phd_smolec.pdf], which in turn
      80              :    !! follows the model of Kuhfuss 1986.
      81              :    !!
      82              :    !! Internally this solves the equation L = L_conv + L_rad.
      83              :    !!
      84              :    !! @param conv_vel_start The convection speed at the start of the step.
      85              :    !! @param mixing_length_alpha The mixing length parameter.
      86              :    !! @param alpha_TDC_DAMP TDC turbulent damping parameter
      87              :    !! @param alpha_TDC_DAMPR TDC radiative damping parameter
      88              :    !! @param alpha_TDC_PtdVdt TDC coefficient on P_turb*dV/dt. Physically should probably be 1.
      89              :    !! @param The time-step (s).
      90              :    !! @param cgrav gravitational constant (erg*cm/g^2).
      91              :    !! @param m Mass inside the face (g).
      92              :    !! @param report Write debug output if true, not if false.
      93              :    !! @param mixing_type Set to semiconvective if convection operates (output).
      94              :    !! @param scale The scale for computing residuals to the luminosity equation (erg/s).
      95              :    !! @param chiT dlnP/dlnT|rho
      96              :    !! @param chiRho dlnP/dlnRho|T
      97              :    !! @param gradr Radiative temperature gradient.
      98              :    !! @param r radial coordinate of the face (cm).
      99              :    !! @param P pressure (erg/cm^3).
     100              :    !! @param T temperature (K).
     101              :    !! @param rho density (g/cm^3).
     102              :    !! @param dV The change in specific volume of the face (cm^3/g) since the start of the step.
     103              :    !! @param Cp Specific heat at constant pressure (erg/g/K).
     104              :    !! @param opacity opacity (cm^2/g).
     105              :    !! @param scale_height The pressure scale-height (cm).
     106              :    !! @param gradL The Ledoux temperature gradient dlnT/dlnP
     107              :    !! @param grada The adiabatic temperature gradient dlnT/dlnP|s
     108              :    !! @param conv_vel The convection speed (cm/s).
     109              :    !! @param D The chemical diffusion coefficient (cm^2/s).
     110              :    !! @param Y_face The superadiabaticity (dlnT/dlnP - grada, output).
     111              :    !! @param gradT The temperature gradient dlnT/dlnP (output).
     112              :    !! @param tdc_num_iters Number of iterations taken in the TDC solver.
     113              :    !! @param ierr Tracks errors (output).
     114        65242 :    subroutine set_TDC( &
     115              :             conv_vel_start, mixing_length_alpha, alpha_TDC_DAMP, alpha_TDC_DAMPR, alpha_TDC_PtdVdt, dt, cgrav, m, report, &
     116              :             mixing_type, scale, chiT, chiRho, gradr, r, P, T, rho, dV, Cp, opacity, &
     117              :             scale_height, gradL, grada, conv_vel, D, Y_face, gradT, tdc_num_iters, max_conv_vel, &
     118              :             Eq_div_w, grav, include_mlt_corr_to_TDC, alpha_TDC_C, alpha_TDC_S, ierr)
     119            0 :       use tdc
     120              :       use tdc_support
     121              :       real(dp), intent(in) :: conv_vel_start, mixing_length_alpha, alpha_TDC_DAMP, alpha_TDC_DAMPR, alpha_TDC_PtdVdt
     122              :       real(dp), intent(in) :: dt, cgrav, m, scale, max_conv_vel, alpha_TDC_c, alpha_TDC_s
     123              :       type(auto_diff_real_star_order1), intent(in) :: &
     124              :          chiT, chiRho, gradr, r, P, T, rho, dV, Cp, opacity, scale_height, gradL, grada, Eq_div_w, grav
     125              :       logical, intent(in) :: report, include_mlt_corr_to_TDC
     126              :       type(auto_diff_real_star_order1),intent(out) :: conv_vel, Y_face, gradT, D
     127              :       integer, intent(out) :: tdc_num_iters, mixing_type, ierr
     128              :       type(tdc_info) :: info
     129              :       type(auto_diff_real_star_order1) :: L, Lambda, Gamma
     130              :       real(dp), parameter :: alpha_c = (1d0/2d0)*sqrt_2_div_3
     131              :       real(dp), parameter :: lower_bound_Z = -1d2
     132              :       real(dp), parameter :: upper_bound_Z = 1d2
     133              :       real(dp), parameter :: eps = 1d-2 ! Threshold in logY for separating multiple solutions.
     134              :       type(auto_diff_real_tdc) :: Zub, Zlb
     135              :       include 'formats'
     136              : 
     137              :       ! Do a call to MLT
     138              :       !grav = cgrav * m / pow2(r)
     139        65242 :       L = 64d0 * pi * boltz_sigma * pow4(T) * grav * pow2(r) * gradr / (3d0 * P * opacity)
     140        65242 :       Lambda = mixing_length_alpha * scale_height
     141              :       call set_MLT('Cox', mixing_length_alpha, 0d0, 0d0, &
     142              :                      chiT, chiRho, Cp, grav, Lambda, rho, P, T, opacity, &
     143              :                      gradr, grada, gradL, &
     144       130484 :                      Gamma, gradT, Y_face, conv_vel, D, mixing_type,1d99, ierr)
     145              : 
     146              : 
     147              :       ! Pack TDC info
     148        65242 :       info%report = report
     149        65242 :       info%include_mlt_corr_to_TDC = include_mlt_corr_to_TDC
     150        65242 :       info%mixing_length_alpha = mixing_length_alpha
     151        65242 :       info%alpha_TDC_DAMP = alpha_TDC_DAMP
     152        65242 :       info%alpha_TDC_DAMPR = alpha_TDC_DAMPR
     153        65242 :       info%alpha_TDC_PtdVdt = alpha_TDC_PtdVdt
     154        65242 :       info%dt = dt
     155        65242 :       info%L = convert(L)
     156        65242 :       info%gradL = convert(gradL)
     157        65242 :       info%grada = convert(grada)
     158        65242 :       info%c0 = convert(alpha_TDC_C * mixing_length_alpha * alpha_c * rho * T * Cp * 4d0 * pi * pow2(r))
     159        65242 :       info%L0 = convert((16d0*pi*crad*clight/3d0)*cgrav*m*pow4(T)/(P*opacity))  ! assumes QHSE for dP/dm, needs correction for if s% make_mlt_hydrodynamic = .false.
     160        65242 :       info%A0 = conv_vel_start/sqrt_2_div_3
     161        65242 :       info%T = T
     162        65242 :       info%rho = rho
     163        65242 :       info%dV = dV
     164        65242 :       info%Cp = Cp
     165        65242 :       info%kap = opacity
     166        65242 :       info%Hp = scale_height
     167        65242 :       info%Gamma = Gamma
     168        65242 :       info%Eq_div_w = Eq_div_w
     169        65242 :       info%alpha_TDC_c = alpha_TDC_C
     170        65242 :       info%alpha_TDC_s = alpha_TDC_S
     171              : 
     172              :       ! Get solution
     173        65242 :       Zub = upper_bound_Z
     174        65242 :       Zlb = lower_bound_Z
     175        65242 :       call get_TDC_solution(info, scale, Zlb, Zub, conv_vel, Y_face, tdc_num_iters, ierr)
     176              : 
     177              :       ! Cap conv_vel at max_conv_vel_div_csound*cs
     178        65242 :       if (conv_vel%val > max_conv_vel) then
     179            0 :          conv_vel = max_conv_vel
     180              :          ! if max_conv_vel = csound,
     181              :          ! L = L0 * (gradL + Y) + c0 * Af * Y_env
     182              :          ! L = L0 * (gradL + Y) + c0 * sqrt_2_div_3 * csound * (Gamma / (1 + Gamma)) * Y
     183              :          ! L - L0 * gradL = Y * (L0 + c0 * sqrt_2_div_3 * csound * (Gamma / (1 + Gamma)))
     184            0 :          if (include_mlt_corr_to_TDC) then
     185              :             Y_face = unconvert(info%L - info%L0 * info%gradL) / &
     186            0 :                (unconvert(info%L0) + unconvert(info%c0) * sqrt_2_div_3 * max_conv_vel * (info%Gamma / (1d0 + info%Gamma)))
     187              :          else
     188              :             Y_face = unconvert(info%L - info%L0 * info%gradL) / &
     189            0 :                (unconvert(info%L0) + unconvert(info%c0) * sqrt_2_div_3 * max_conv_vel)
     190              :          end if
     191              :       end if
     192              : 
     193              :       ! Unpack output
     194        65242 :       gradT = Y_face + gradL
     195        65242 :       D = conv_vel*scale_height*mixing_length_alpha/3d0     ! diffusion coefficient [cm^2/sec]
     196        65242 :       if (conv_vel > 0d0) then
     197         8997 :          mixing_type = convective_mixing
     198              :       else
     199        56245 :          mixing_type = no_mixing
     200              :       end if
     201        65242 :    end subroutine set_TDC
     202              : 
     203              :    !> Calculates the outputs of semiconvective mixing theory.
     204              :    !!
     205              :    !! @param L Luminosity across a face (erg/s).
     206              :    !! @param Lambda The mixing length (cm).
     207              :    !! @param m Mass inside the face (g).
     208              :    !! @param T temperature (K).
     209              :    !! @param P pressure (erg/cm^3).
     210              :    !! @param Pr radiation pressure (erg/cm^3).
     211              :    !! @param beta ratio of gas pressure to radiation pressure.
     212              :    !! @param opacity opacity (cm^2/g).
     213              :    !! @param rho density (g/cm^3).
     214              :    !! @param alpha_semiconvection The semiconvective alpha parameter.
     215              :    !! @param semiconvection_option A string specifying which semiconvection theory to use. Currently supported are 'Langer_85 mixing; gradT = gradr' and 'Langer_85'.
     216              :    !! @param cgrav gravitational constant (erg*cm/g^2).
     217              :    !! @param Cp Specific heat at constant pressure (erg/g/K).
     218              :    !! @param gradr The radiative temperature gradient dlnT/dlnP_{rad}
     219              :    !! @param grada The adiabatic temperature gradient dlnT/dlnP|s
     220              :    !! @param gradL The Ledoux temperature gradient dlnT/dlnP
     221              :    !! @param gradL_composition_term The contribution of composition gradients to the Ledoux temperature gradient.
     222              :    !! @param gradT The temperature gradient dlnT/dlnP (output).
     223              :    !! @param Y_face The superadiabaticity (dlnT/dlnP - grada, output).
     224              :    !! @param conv_vel The convection speed (cm/s).
     225              :    !! @param D The chemical diffusion coefficient (cm^2/s).
     226              :    !! @param mixing_type Set to semiconvective if convection operates (output).
     227              :    !! @param ierr Tracks errors (output).
     228            0 :    subroutine set_semiconvection(L, Lambda, m, T, P, Pr, beta, opacity, rho, alpha_semiconvection, &
     229              :                                  semiconvection_option, cgrav, Cp, gradr, grada, gradL, &
     230              :                                  gradL_composition_term, &
     231              :                                  gradT, Y_face, conv_vel, D, mixing_type, ierr)
     232        65242 :       use semiconvection
     233              :       type(auto_diff_real_star_order1), intent(in) :: L, Lambda, T, P, Pr, beta, opacity, rho
     234              :       type(auto_diff_real_star_order1), intent(in) :: Cp, gradr, grada, gradL
     235              :       character(len=*), intent(in) :: semiconvection_option
     236              :       real(dp), intent(in) :: alpha_semiconvection, cgrav, gradL_composition_term, m
     237              :       type(auto_diff_real_star_order1), intent(out) :: gradT, Y_face, conv_vel, D
     238              :       integer, intent(out) :: mixing_type, ierr
     239              : 
     240              :       call calc_semiconvection(L, Lambda, m, T, P, Pr, beta, opacity, rho, alpha_semiconvection, &
     241              :                                  semiconvection_option, cgrav, Cp, gradr, grada, gradL, &
     242              :                                  gradL_composition_term, &
     243            0 :                                  gradT, Y_face, conv_vel, D, mixing_type, ierr)
     244            0 :    end subroutine set_semiconvection
     245              : 
     246              :    !> Calculates the outputs of convective mixing length theory.
     247              :    !!
     248              :    !! @param MLT_option A string specifying which MLT option to use. Currently supported are Cox, Henyey, ML1, ML2, Mihalas.
     249              :    !!                   Note that 'TDC' is also a valid input and will return the Cox result.
     250              :    !!                   This is for use when falling back from TDC -> MLT, as Cox is the most-similar prescription to TDC.
     251              :    !! @param mixing_length_alpha The mixing length parameter.
     252              :    !! @param Henyey_MLT_nu_param The nu parameter in Henyey's MLT prescription.
     253              :    !! @param Henyey_MLT_y_param The y parameter in Henyey's MLT prescription.
     254              :    !! @param chiT dlnP/dlnT|rho
     255              :    !! @param chiRho dlnP/dlnRho|T
     256              :    !! @param Cp Specific heat at constant pressure (erg/g/K).
     257              :    !! @param grav The acceleration due to gravity (cm/s^2).
     258              :    !! @param Lambda The mixing length (cm).
     259              :    !! @param rho density (g/cm^3).
     260              :    !! @param T temperature (K).
     261              :    !! @param opacity opacity (cm^2/g)
     262              :    !! @param gradr The radiative temperature gradient dlnT/dlnP_{rad}
     263              :    !! @param grada The adiabatic temperature gradient dlnT/dlnP|s
     264              :    !! @param gradL The Ledoux temperature gradient dlnT/dlnP
     265              :    !! @param Gamma The convective efficiency parameter (output).
     266              :    !! @param gradT The temperature gradient dlnT/dlnP (output).
     267              :    !! @param Y_face The superadiabaticity (dlnT/dlnP - grada, output).
     268              :    !! @param conv_vel The convection speed (cm/s).
     269              :    !! @param D The chemical diffusion coefficient (cm^2/s).
     270              :    !! @param mixing_type Set to convective if convection operates (output).
     271              :    !! @param ierr Tracks errors (output).
     272        67974 :    subroutine set_MLT(MLT_option, mixing_length_alpha, Henyey_MLT_nu_param, Henyey_MLT_y_param, &
     273              :                      chiT, chiRho, Cp, grav, Lambda, rho, P, T, opacity, &
     274              :                      gradr, grada, gradL, &
     275              :                      Gamma, gradT, Y_face, conv_vel, D, mixing_type, max_conv_vel, ierr)
     276              :       use mlt
     277              :       type(auto_diff_real_star_order1), intent(in) :: chiT, chiRho, Cp, grav, Lambda, rho, P, T, opacity, gradr, grada, gradL
     278              :       character(len=*), intent(in) :: MLT_option
     279              :       real(dp), intent(in) :: mixing_length_alpha, Henyey_MLT_nu_param, Henyey_MLT_y_param, max_conv_vel
     280              : 
     281              :       type(auto_diff_real_star_order1), intent(out) :: Gamma, gradT, Y_face, conv_vel, D
     282              :       integer, intent(out) :: mixing_type, ierr
     283              : 
     284              :       call calc_MLT(MLT_option, mixing_length_alpha, Henyey_MLT_nu_param, Henyey_MLT_y_param, &
     285              :                      chiT, chiRho, Cp, grav, Lambda, rho, P, T, opacity, &
     286              :                      gradr, grada, gradL, &
     287        67974 :                      Gamma, gradT, Y_face, conv_vel, D, mixing_type, max_conv_vel, ierr)
     288              : 
     289         2732 :    end subroutine set_MLT
     290              : 
     291              : end module turb
        

Generated by: LCOV version 2.0-1