LCOV - code coverage report
Current view: top level - star/private - turb_info.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 46.0 % 289 133
Test Date: 2025-05-08 18:23:42 Functions: 81.8 % 11 9

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2021  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              : 
      21              :       module turb_info
      22              : 
      23              :       use star_private_def
      24              :       use const_def, only: dp, i8, ln10, pi4, no_mixing, convective_mixing, crystallized, phase_separation_mixing
      25              :       use num_lib
      26              :       use utils_lib
      27              :       use auto_diff_support
      28              : 
      29              :       implicit none
      30              : 
      31              :       private
      32              :       public :: set_mlt_vars  ! for hydro_vars and conv_premix
      33              :       public :: do1_mlt_2  ! for predictive_mix
      34              :       public :: switch_to_radiative  ! mix_info
      35              :       public :: check_for_redo_MLT  ! for hydro_vars
      36              :       public :: set_gradT_excess_alpha  ! for evolve
      37              : 
      38              :       contains
      39              : 
      40           66 :       subroutine set_mlt_vars(s, nzlo, nzhi, ierr)
      41              :          use star_utils, only: start_time, update_time
      42              :          type (star_info), pointer :: s
      43              :          integer, intent(in) :: nzlo, nzhi
      44              :          integer, intent(out) :: ierr
      45              :          integer :: k, op_err
      46              :          integer(i8) :: time0
      47           66 :          real(dp) :: total
      48              :          logical :: make_gradr_sticky_in_solver_iters
      49              :          include 'formats'
      50           66 :          ierr = 0
      51           66 :          if (s% doing_timing) call start_time(s, time0, total)
      52           66 : !$OMP PARALLEL DO PRIVATE(k,op_err,make_gradr_sticky_in_solver_iters) SCHEDULE(dynamic,2)
      53              :          do k = nzlo, nzhi
      54              :             op_err = 0
      55              :             call do1_mlt_2(s, k, make_gradr_sticky_in_solver_iters, op_err)
      56              :             if (make_gradr_sticky_in_solver_iters .and. s% solver_iter > 3) then
      57              :                if (.not. s% fixed_gradr_for_rest_of_solver_iters(k)) then
      58              :                   s% fixed_gradr_for_rest_of_solver_iters(k) = &
      59              :                      (s% mlt_mixing_type(k) == no_mixing)
      60              :                end if
      61              :             end if
      62              :             if (op_err /= 0) ierr = op_err
      63              :          end do
      64              : !$OMP END PARALLEL DO
      65           66 :          if (s% doing_timing) call update_time(s, time0, total, s% time_mlt)
      66              : 
      67           66 :       end subroutine set_mlt_vars
      68              : 
      69              : 
      70        79994 :       subroutine do1_mlt_2(s, k, &
      71              :             make_gradr_sticky_in_solver_iters, ierr, &
      72              :             mixing_length_alpha_in, gradL_composition_term_in)
      73              :          ! get convection info for point k
      74           66 :          use star_utils
      75              :          use turb_support, only: do1_mlt_eval
      76              :          use eos_def
      77              :          use auto_diff_support
      78              :          type (star_info), pointer :: s
      79              :          integer, intent(in) :: k
      80              :          logical, intent(out) :: make_gradr_sticky_in_solver_iters
      81              :          integer, intent(out) :: ierr
      82              :          real(dp), intent(in), optional :: &
      83              :             mixing_length_alpha_in, gradL_composition_term_in
      84              : 
      85              :          type(auto_diff_real_star_order1) :: gradr_factor
      86        79994 :          real(dp) :: f, gradL_composition_term, abs_du_div_cs, cs, mixing_length_alpha
      87        79994 :          real(dp), pointer :: vel(:)
      88              :          integer :: i, mixing_type, nz, k_T_max
      89              :          real(dp), parameter :: conv_vel_mach_limit = 0.9d0
      90        79994 :          real(dp) :: crystal_pad
      91              :          logical :: no_mix
      92              :          type(auto_diff_real_star_order1) :: &
      93              :             grada_face_ad, scale_height_ad, gradr_ad, rho_face_ad, &
      94              :             gradT_ad, Y_face_ad, mlt_vc_ad, D_ad, Gamma_ad
      95              :          include 'formats'
      96              : 
      97        79994 :          ierr = 0
      98        79994 :          nz = s% nz
      99              : 
     100        79994 :          if (k < 1 .or. k > nz) then
     101            0 :             write(*,3) 'bad k for do1_mlt', k, nz
     102            0 :             ierr = -1
     103            0 :             return
     104              :             call mesa_error(__FILE__,__LINE__)
     105              :          end if
     106              : 
     107        79994 :          if (present(mixing_length_alpha_in)) then
     108            0 :             mixing_length_alpha = mixing_length_alpha_in
     109              :          else
     110        79994 :             mixing_length_alpha = s% mixing_length_alpha
     111              :          end if
     112              : 
     113        79994 :          if (present(gradL_composition_term_in)) then
     114            0 :             gradL_composition_term = gradL_composition_term_in
     115        79994 :          else if (s% use_Ledoux_criterion) then
     116            0 :             gradL_composition_term = s% gradL_composition_term(k)
     117              :          else
     118        79994 :             gradL_composition_term = 0d0
     119              :          end if
     120              : 
     121        79994 :          grada_face_ad = get_grada_face(s,k)
     122        79994 :          scale_height_ad = get_scale_height_face(s,k)
     123        79994 :          gradr_ad = get_gradr_face(s,k)
     124              : 
     125        79994 :          if (s% rotation_flag .and. s% mlt_use_rotation_correction) then
     126            0 :             gradr_factor = s% ft_rot(k)/s% fp_rot(k)*s% gradr_factor(k)
     127              :          else
     128        79994 :             gradr_factor = s% gradr_factor(k)
     129              :          end if
     130        79994 :          if (is_bad_num(gradr_factor% val)) then
     131            0 :             ierr = -1
     132            0 :             return
     133              :          end if
     134        79994 :          gradr_ad = gradr_ad*gradr_factor
     135              : 
     136              :          ! now can call set_no_mixing if necessary
     137              : 
     138        79994 :          if (k == 1 .and. s% mlt_make_surface_no_mixing) then
     139            0 :             call set_no_mixing('surface_no_mixing')
     140            0 :             return
     141              :          end if
     142              : 
     143        79994 :          crystal_pad = s% min_dq * s% m(1) * 0.5d0
     144              :          if ((s% phase(k) > 0.5d0 .and. s% mu(k) > 1.7d0) &
     145        79994 :               .or. s% crystal_core_boundary_mass + crystal_pad > s% m(k)) then
     146              :             ! mu(k) check is so that we only evaluate this in C/O dominated material or heavier.
     147              :             ! Helium can return bad phase info on Skye, so we don't want it to shut off
     148              :             ! convection because of wrong phase information.
     149            0 :             call set_no_mixing('solid_no_mixing')
     150            0 :             s% mlt_mixing_type(k) = crystallized
     151            0 :             return
     152              :          end if
     153              : 
     154        79994 :          if (s% m(k) <= s% phase_sep_mixing_mass) then
     155              :             ! Treat as radiative for MLT purposes, and label as already mixed by phase separation
     156            0 :             call set_no_mixing('phase_separation_mixing')
     157            0 :             s% mlt_mixing_type(k) = phase_separation_mixing
     158            0 :             return
     159              :          end if
     160              : 
     161        79994 :          if (s% lnT_start(k)/ln10 > s% max_logT_for_mlt) then
     162            0 :             call set_no_mixing('max_logT')
     163            0 :             return
     164              :          end if
     165              : 
     166        79994 :          if (s% no_MLT_below_shock .and. (s%u_flag .or. s%v_flag)) then  ! check for outward shock above k
     167            0 :             if (s% u_flag) then
     168            0 :                vel => s% u
     169              :             else
     170            0 :                vel => s% v
     171              :             end if
     172            0 :             do i=k-1,1,-1
     173            0 :                cs = s% csound(i)
     174        79994 :                if (vel(i+1) >= cs .and. vel(i) < cs) then
     175            0 :                   call set_no_mixing('below_shock')
     176            0 :                   return
     177              :                end if
     178              :             end do
     179              :          end if
     180              : 
     181        79994 :          if (s% csound_start(k) > 0d0 .and. (s% u_flag .or. s% v_flag)) then
     182            0 :             no_mix = .false.
     183            0 :             if (s% u_flag) then
     184            0 :                vel => s% u_start
     185              :             else
     186            0 :                vel => s% v_start
     187              :             end if
     188            0 :             abs_du_div_cs = 0d0
     189            0 :             if (vel(k)/1d5 > s% max_v_for_convection) then
     190              :                no_mix = .true.
     191            0 :             else if (s% q(k) > s% max_q_for_convection_with_hydro_on) then
     192              :                no_mix = .true.
     193            0 :             else if ((abs(vel(k))) >= &
     194              :                   s% csound_start(k)*s% max_v_div_cs_for_convection) then
     195              :                no_mix = .true.
     196            0 :             else if (s% u_flag) then
     197            0 :                if (k == 1) then
     198              :                   abs_du_div_cs = 1d99
     199            0 :                else if (k < nz) then
     200              :                   abs_du_div_cs = max(abs(vel(k) - vel(k+1)), &
     201            0 :                       abs(vel(k) - vel(k-1))) / s% csound_start(k)
     202              :                end if
     203            0 :                if (abs_du_div_cs > s% max_abs_du_div_cs_for_convection) then
     204              :                   no_mix = .true.
     205              :                end if
     206              :             end if
     207              :             if (no_mix) then
     208            0 :                call set_no_mixing('no_mix')
     209            0 :                return
     210              :             end if
     211              :          end if
     212              : 
     213        79994 :          make_gradr_sticky_in_solver_iters = s% make_gradr_sticky_in_solver_iters
     214        79994 :          if (.not. make_gradr_sticky_in_solver_iters .and. &
     215              :                s% min_logT_for_make_gradr_sticky_in_solver_iters < 1d20) then
     216            0 :             k_T_max = maxloc(s% lnT_start(1:nz),dim=1)
     217              :             make_gradr_sticky_in_solver_iters = &
     218            0 :                (s% lnT_start(k_T_max)/ln10 >= s% min_logT_for_make_gradr_sticky_in_solver_iters)
     219              :          end if
     220        79994 :          if (make_gradr_sticky_in_solver_iters .and. s% fixed_gradr_for_rest_of_solver_iters(k)) then
     221            0 :             call set_no_mixing('gradr_sticky')
     222            0 :             return
     223              :          end if
     224              : 
     225              :          call do1_mlt_eval(s, k, s% MLT_option, gradL_composition_term, &
     226              :             gradr_ad, grada_face_ad, scale_height_ad, mixing_length_alpha, &
     227        79994 :             mixing_type, gradT_ad, Y_face_ad, mlt_vc_ad, D_ad, Gamma_ad, ierr)
     228        79994 :          if (ierr /= 0) then
     229            0 :             if (s% report_ierr) then
     230            0 :                write(*,*) 'ierr in do1_mlt_eval for k', k
     231              :             end if
     232            0 :             return
     233              :          end if
     234              : 
     235        79994 :          call store_results
     236              : 
     237        79994 :          if (s% mlt_gradT_fraction >= 0d0 .and. s% mlt_gradT_fraction <= 1d0) then
     238            0 :             f = s% mlt_gradT_fraction
     239              :          else
     240        79994 :             f = s% adjust_mlt_gradT_fraction(k)
     241              :          end if
     242        79994 :          call adjust_gradT_fraction(s, k, f)
     243              : 
     244       239982 :          if (s% mlt_mixing_type(k) == no_mixing .or. abs(s% gradr(k)) < 1d-20) then
     245        68285 :             s% L_conv(k) = 0d0
     246              :          else
     247        11709 :             s% L_conv(k) = s% L(k) * (1d0 - s% gradT(k)/s% gradr(k))  ! C&G 14.109
     248              :          end if
     249              : 
     250              :          contains
     251              : 
     252        79994 :          subroutine store_results
     253        79994 :             s% mlt_mixing_type(k) = mixing_type
     254              : 
     255        79994 :             s% grada_face_ad(k) = grada_face_ad
     256        79994 :             s% grada_face(k) = grada_face_ad%val
     257              : 
     258        79994 :             s% gradT_ad(k) = gradT_ad
     259        79994 :             s% gradT(k) = s% gradT_ad(k)%val
     260        79994 :             s% mlt_gradT(k) = s% gradT(k)  ! prior to adjustments
     261              : 
     262        79994 :             s% Y_face_ad(k) = Y_face_ad
     263        79994 :             s% Y_face(k) = s% Y_face_ad(k)%val
     264              : 
     265        79994 :             s% mlt_vc_ad(k) = mlt_vc_ad
     266        79994 :             if (s% okay_to_set_mlt_vc) s% mlt_vc(k) = s% mlt_vc_ad(k)%val
     267              : 
     268        79994 :             s% mlt_D_ad(k) = D_ad
     269        79994 :             s% mlt_D(k) = D_ad%val
     270              : 
     271        79994 :             rho_face_ad = get_rho_face(s,k)
     272        79994 :             s% mlt_cdc(k) = s% mlt_D(k)*pow2(pi4*pow2(s%r(k))*rho_face_ad%val)
     273              : 
     274        79994 :             s% mlt_Gamma_ad(k) = Gamma_ad
     275        79994 :             s% mlt_Gamma(k) = Gamma_ad%val
     276              : 
     277        79994 :             s% gradr_ad(k) = gradr_ad
     278        79994 :             s% gradr(k) = s% gradr_ad(k)%val
     279              : 
     280        79994 :             s% gradL_ad(k) = s% grada_face_ad(k) + gradL_composition_term
     281        79994 :             s% gradL(k) = s% gradL_ad(k)%val
     282              : 
     283        79994 :             s% scale_height_ad(k) = scale_height_ad
     284        79994 :             s% scale_height(k) = scale_height_ad%val
     285              : 
     286        79994 :             s% Lambda_ad(k) = mixing_length_alpha*scale_height_ad
     287        79994 :             s% mlt_mixing_length(k) = s% Lambda_ad(k)%val
     288              : 
     289        79994 :          end subroutine store_results
     290              : 
     291            0 :          subroutine set_no_mixing(str)
     292              :             character (len=*) :: str
     293              :             include 'formats'
     294              : 
     295            0 :             s% mlt_mixing_type(k) = no_mixing
     296              : 
     297            0 :             s% grada_face_ad(k) = grada_face_ad
     298            0 :             s% grada_face(k) = grada_face_ad%val
     299              : 
     300              :             gradT_ad = gradr_ad
     301            0 :             s% gradT_ad(k) = gradT_ad
     302            0 :             s% gradT(k) = s% gradT_ad(k)%val
     303              : 
     304            0 :             Y_face_ad = gradT_ad - grada_face_ad
     305            0 :             s% Y_face_ad(k) = Y_face_ad
     306            0 :             s% Y_face(k) = s% Y_face_ad(k)%val
     307              : 
     308            0 :             s% mlt_vc_ad(k) = 0d0
     309            0 :             if (s% okay_to_set_mlt_vc) s% mlt_vc(k) = 0d0
     310              : 
     311            0 :             s% mlt_D_ad(k) = 0d0
     312            0 :             s% mlt_D(k) = 0d0
     313            0 :             s% mlt_cdc(k) = 0d0
     314              : 
     315            0 :             s% mlt_Gamma_ad(k) = 0d0
     316            0 :             s% mlt_Gamma(k) = 0d0
     317              : 
     318            0 :             s% gradr_ad(k) = gradr_ad
     319            0 :             s% gradr(k) = s% gradr_ad(k)%val
     320              : 
     321            0 :             s% gradL_ad(k) = 0d0
     322            0 :             s% gradL(k) = 0d0
     323              : 
     324            0 :             s% scale_height_ad(k) = scale_height_ad
     325            0 :             s% scale_height(k) = scale_height_ad%val
     326              : 
     327            0 :             s% Lambda_ad(k) = mixing_length_alpha*scale_height_ad
     328            0 :             s% mlt_mixing_length(k) = s% Lambda_ad(k)%val
     329              : 
     330            0 :             s% L_conv(k) = 0d0
     331              : 
     332            0 :          end subroutine set_no_mixing
     333              : 
     334              :       end subroutine do1_mlt_2
     335              : 
     336              : 
     337        79994 :       subroutine adjust_gradT_fraction(s,k,f)
     338              :          ! replace gradT by combo of grada_face and gradr
     339              :          ! then check excess
     340              :          use eos_def
     341              :          type (star_info), pointer :: s
     342              :          real(dp), intent(in) :: f
     343              :          integer, intent(in) :: k
     344              :          include 'formats'
     345        79994 :          if (f >= 0.0d0 .and. f <= 1.0d0) then
     346            0 :             if (f == 0d0) then
     347            0 :                s% gradT_ad(k) = s% gradr_ad(k)
     348              :             else  ! mix
     349            0 :                s% gradT_ad(k) = f*s% grada_face_ad(k) + (1.0d0 - f)*s% gradr_ad(k)
     350              :             end if
     351            0 :             s% gradT(k) = s% gradT_ad(k)%val
     352              :          end if
     353        79994 :          call adjust_gradT_excess(s, k)
     354        79994 :          s% gradT_sub_grada(k) = s% gradT(k) - s% grada_face(k)
     355        79994 :       end subroutine adjust_gradT_fraction
     356              : 
     357              : 
     358        79994 :       subroutine adjust_gradT_excess(s, k)
     359        79994 :          use eos_def
     360              :          type (star_info), pointer :: s
     361              :          integer, intent(in) :: k
     362        79994 :          real(dp) :: alfa, log_tau, gradT_excess_alpha, gradT_sub_grada
     363              :          include 'formats'
     364              :          !s% gradT_excess_alpha is calculated at start of step and held constant during iterations
     365              :          ! gradT_excess_alpha = 0 means no efficiency boost; = 1 means full efficiency boost
     366        79994 :          gradT_excess_alpha = s% gradT_excess_alpha
     367        79994 :          s% gradT_excess_effect(k) = 0.0d0
     368        79994 :          gradT_sub_grada = s% gradT(k) - s% grada_face(k)
     369        79994 :          if (gradT_excess_alpha <= 0.0d0  .or. &
     370              :              gradT_sub_grada <= s% gradT_excess_f1) return
     371            0 :          if (s% lnT(k)/ln10 > s% gradT_excess_max_logT) return
     372            0 :          log_tau = log10(s% tau(k))
     373            0 :          if (log_tau < s% gradT_excess_max_log_tau_full_off) return
     374            0 :          if (log_tau < s% gradT_excess_min_log_tau_full_on) &
     375              :             gradT_excess_alpha = gradT_excess_alpha* &
     376              :                (log_tau - s% gradT_excess_max_log_tau_full_off)/ &
     377            0 :                (s% gradT_excess_min_log_tau_full_on - s% gradT_excess_max_log_tau_full_off)
     378            0 :          alfa = s% gradT_excess_f2  ! for full boost, use this fraction of gradT
     379            0 :          if (gradT_excess_alpha < 1) &  ! only partial boost, so increase alfa
     380              :             ! alfa goes to 1 as gradT_excess_alpha goes to 0
     381              :             ! alfa unchanged as gradT_excess_alpha goes to 1
     382            0 :             alfa = alfa + (1d0 - alfa)*(1d0 - gradT_excess_alpha)
     383            0 :          s% gradT_ad(k) = alfa*s% gradT_ad(k) + (1d0 - alfa)*s% grada_face_ad(k)
     384            0 :          s% gradT(k) = s% gradT_ad(k)%val
     385            0 :          s% gradT_excess_effect(k) = 1d0 - alfa
     386        79994 :       end subroutine adjust_gradT_excess
     387              : 
     388              : 
     389           30 :       subroutine switch_to_radiative(s,k)
     390              :          type (star_info), pointer :: s
     391              :          integer, intent(in) :: k
     392           30 :          s% mlt_mixing_type(k) = no_mixing
     393           30 :          s% mlt_mixing_length(k) = 0
     394           30 :          s% mlt_D(k) = 0
     395           30 :          s% mlt_cdc(k) = 0d0
     396           30 :          s% mlt_vc(k) = 0
     397           30 :          s% gradT_ad(k) = s% gradr_ad(k)
     398           30 :          s% gradT(k) = s% gradT_ad(k)%val
     399        79994 :       end subroutine switch_to_radiative
     400              : 
     401              : 
     402              :       subroutine switch_to_adiabatic(s,k)
     403              :          use eos_def, only: i_grad_ad
     404              :          type (star_info), pointer :: s
     405              :          integer, intent(in) :: k
     406              :          s% gradT_ad(k) = s% grada_face_ad(k)
     407              :          s% gradT(k) = s% gradT_ad(k)%val
     408              :       end subroutine switch_to_adiabatic
     409              : 
     410              : 
     411           21 :       subroutine set_gradT_excess_alpha(s, ierr)
     412              :          use alloc
     413              :          use star_utils, only: get_Lrad_div_Ledd, after_C_burn
     414              :          use chem_def, only: ih1, ihe4
     415              :          type (star_info), pointer :: s
     416              :          integer, intent(out) :: ierr
     417           21 :          real(dp) :: beta, lambda, tmp, alpha, &
     418           21 :             beta_limit, lambda1, beta1, lambda2, beta2, dlambda, dbeta
     419              :          integer :: k, k_beta, k_lambda, nz, h1, he4
     420              :          include 'formats'
     421           21 :          ierr = 0
     422           21 :          if (.not. s% okay_to_reduce_gradT_excess) then
     423           21 :             s% gradT_excess_alpha = 0
     424           21 :             return
     425              :          end if
     426            0 :          nz = s% nz
     427            0 :          h1 = s% net_iso(ih1)
     428            0 :          if (h1 /= 0) then
     429            0 :             if (s% xa(h1,nz) > s% gradT_excess_max_center_h1) then
     430            0 :                s% gradT_excess_alpha = 0
     431            0 :                return
     432              :             end if
     433              :          end if
     434            0 :          he4 = s% net_iso(ihe4)
     435            0 :          if (he4 /= 0) then
     436            0 :             if (s% xa(he4,nz) < s% gradT_excess_min_center_he4) then
     437            0 :                s% gradT_excess_alpha = 0
     438            0 :                return
     439              :             end if
     440              :          end if
     441            0 :          beta = 1d0  ! beta = min over k of Pgas(k)/Peos(k)
     442            0 :          k_beta = 0
     443            0 :          do k=1,nz
     444            0 :             tmp = s% Pgas(k)/s% Peos(k)
     445            0 :             if (tmp < beta) then
     446            0 :                k_beta = k
     447            0 :                beta = tmp
     448              :             end if
     449              :          end do
     450            0 :          beta = beta*(1d0 + s% xa(1,nz))
     451            0 :          s% gradT_excess_min_beta = beta
     452            0 :          lambda = 0d0  ! lambda = max over k of Lrad(k)/Ledd(k)
     453            0 :          do k=2,k_beta
     454            0 :             tmp = get_Lrad_div_Ledd(s,k)
     455            0 :             if (tmp > lambda) then
     456            0 :                k_lambda = k
     457            0 :                lambda = tmp
     458              :             end if
     459              :          end do
     460            0 :          lambda = min(1d0,lambda)
     461            0 :          s% gradT_excess_max_lambda = lambda
     462            0 :          lambda1 = s% gradT_excess_lambda1
     463            0 :          beta1 = s% gradT_excess_beta1
     464            0 :          lambda2 = s% gradT_excess_lambda2
     465            0 :          beta2 = s% gradT_excess_beta2
     466            0 :          dlambda = s% gradT_excess_dlambda
     467            0 :          dbeta = s% gradT_excess_dbeta
     468              :          ! alpha is fraction of full boost to apply
     469              :          ! depends on location in (beta,lambda) plane
     470            0 :          if (lambda1 < 0) then
     471              :             alpha = 1
     472            0 :          else if (lambda >= lambda1) then
     473            0 :             if (beta <= beta1) then
     474              :                alpha = 1
     475            0 :             else if (beta < beta1 + dbeta) then
     476            0 :                alpha = (beta1 + dbeta - beta)/dbeta
     477              :             else  ! beta >= beta1 + dbeta
     478              :                alpha = 0
     479              :             end if
     480            0 :          else if (lambda >= lambda2) then
     481              :             beta_limit = beta2 + &
     482            0 :                (lambda - lambda2)*(beta1 - beta2)/(lambda1 - lambda2)
     483            0 :             if (beta <= beta_limit) then
     484              :                alpha = 1
     485            0 :             else if (beta < beta_limit + dbeta) then
     486            0 :                alpha = (beta_limit + dbeta - beta)/dbeta
     487              :             else
     488              :                alpha = 0
     489              :             end if
     490            0 :          else if (lambda > lambda2 - dlambda) then
     491            0 :             if (beta <= beta2) then
     492              :                alpha = 1
     493            0 :             else if (beta < beta2 + dbeta) then
     494            0 :                alpha = (lambda - (lambda2 - dlambda))/dlambda
     495              :             else  ! beta >= beta2 + dbeta
     496              :                alpha = 0
     497              :             end if
     498              :          else  ! lambda <= lambda2 - dlambda
     499              :             alpha = 0
     500              :          end if
     501            0 :          if (s% generations > 1 .and. lambda1 >= 0) then  ! time smoothing
     502              :             s% gradT_excess_alpha = &
     503              :                (1d0 - s% gradT_excess_age_fraction)*alpha + &
     504            0 :                s% gradT_excess_age_fraction*s% gradT_excess_alpha_old
     505            0 :             if (s% gradT_excess_max_change > 0d0) then
     506            0 :                if (s% gradT_excess_alpha > s% gradT_excess_alpha_old) then
     507              :                   s% gradT_excess_alpha = min(s% gradT_excess_alpha, s% gradT_excess_alpha_old + &
     508            0 :                      s% gradT_excess_max_change)
     509              :                else
     510              :                   s% gradT_excess_alpha = max(s% gradT_excess_alpha, s% gradT_excess_alpha_old - &
     511            0 :                      s% gradT_excess_max_change)
     512              :                end if
     513              :             end if
     514              :          else
     515            0 :             s% gradT_excess_alpha = alpha
     516              :          end if
     517            0 :          if (s% gradT_excess_alpha < 1d-4) s% gradT_excess_alpha = 0d0
     518            0 :          if (s% gradT_excess_alpha > 0.9999d0) s% gradT_excess_alpha = 1d0
     519           21 :       end subroutine set_gradT_excess_alpha
     520              : 
     521              : 
     522           66 :       subroutine check_for_redo_MLT(s, nzlo, nzhi, ierr)
     523              :          type (star_info), pointer :: s
     524              :          integer, intent(in) :: nzlo, nzhi
     525              :          integer, intent(out) :: ierr
     526              :          logical :: in_convective_region
     527              :          integer :: k, k_bot
     528           66 :          real(dp) :: bot_Hp, bot_r, top_Hp, top_r, dr
     529              :          logical :: dbg
     530              :          include 'formats'
     531              :          ! check_for_redo_MLT assumes that nzlo = 1, nzhi = nz
     532              :          ! that is presently true; make sure that assumption doesn't change
     533           66 :          if (.not. ((nzlo==1).and.(nzhi==s%nz))) then
     534            0 :             write(*,*) 'nzlo != 1 or nzhi != nz'
     535            0 :             call mesa_error(__FILE__,__LINE__)
     536              :          end if
     537           66 :          ierr = 0
     538           66 :          dbg = .false.
     539           66 :          bot_Hp = 0; bot_r = 0; top_Hp = 0; top_r = 0; dr = 0
     540           66 :          in_convective_region = (s% mlt_mixing_type(nzhi) == convective_mixing)
     541           66 :          k_bot = nzhi
     542           66 :          bot_r = s% r(k_bot)
     543           66 :          bot_Hp = s% scale_height(k_bot)
     544        79928 :          do k=nzhi-1, nzlo+1, -1
     545        79928 :             if (in_convective_region) then
     546        11709 :                if (s% mlt_mixing_type(k) /= convective_mixing) then
     547          198 :                   call end_of_convective_region
     548              :                end if
     549              :             else  ! in non-convective region
     550        68153 :                if (s% mlt_mixing_type(k) == convective_mixing) then
     551              :                   ! start of a convective region
     552          132 :                   k_bot = k+1
     553          132 :                   in_convective_region = .true.
     554          132 :                   bot_r = s% r(k_bot)
     555          132 :                   bot_Hp = s% scale_height(k_bot)
     556              :                end if
     557              :             end if
     558              :          end do
     559           87 :          if (in_convective_region) then
     560            0 :             k = 1  ! end at top
     561            0 :             call end_of_convective_region
     562              :          end if
     563              : 
     564              :          contains
     565              : 
     566          198 :          subroutine end_of_convective_region()
     567              :             integer :: kk, op_err
     568          198 :             real(dp) :: Hp
     569              :             logical :: end_dbg
     570              :             9 format(a40, 3i7, 99(1pd26.16))
     571              :             include 'formats'
     572          198 :             in_convective_region = .false.
     573          198 :             end_dbg = .false.
     574          198 :             top_r = s% r(k)
     575          198 :             top_Hp = s% scale_height(k)
     576          198 :             dr = top_r - bot_r
     577          198 :             Hp = (bot_Hp + top_Hp)/2
     578          198 :             if (dr < s% alpha_mlt(k)*min(top_Hp, bot_Hp) .and. &
     579              :                   s% redo_conv_for_dr_lt_mixing_length) then
     580            0 : !$OMP PARALLEL DO PRIVATE(kk,op_err) SCHEDULE(dynamic,2)
     581              :                do kk = k, k_bot
     582              :                   op_err = 0
     583              :                   call redo1_mlt(s,kk,dr,op_err)
     584              :                   if (op_err /= 0) ierr = op_err
     585              :                end do
     586              : !$OMP END PARALLEL DO
     587              :             end if
     588          198 :          end subroutine end_of_convective_region
     589              : 
     590            0 :          subroutine redo1_mlt(s, k, dr, ierr)
     591              :             type (star_info), pointer :: s
     592              :             integer, intent(in) :: k
     593              :             real(dp), intent(in) :: dr
     594              :             integer, intent(out) :: ierr
     595              :             logical :: make_gradr_sticky_in_solver_iters
     596              :             include 'formats'
     597            0 :             ierr = 0
     598            0 :             if (dr >= s% mlt_mixing_length(k)) return
     599              :             ! if convection zone is smaller than mixing length
     600              :             ! redo MLT with reduced alpha so mixing_length = dr
     601              :             call do1_mlt_2(s, k, make_gradr_sticky_in_solver_iters, ierr, &
     602            0 :                mixing_length_alpha_in = dr/s% scale_height(k))
     603              :          end subroutine redo1_mlt
     604              : 
     605              :       end subroutine check_for_redo_MLT
     606              : 
     607              : 
     608              :       end module turb_info
        

Generated by: LCOV version 2.0-1