LCOV - code coverage report
Current view: top level - star/private - overshoot_utils.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 112 0
Test Date: 2025-05-08 18:23:42 Functions: 0.0 % 4 0

            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 overshoot_utils
      21              : 
      22              :   use num_lib
      23              :   use star_private_def
      24              : 
      25              :   implicit none
      26              : 
      27              :   private
      28              :   public :: eval_conv_bdy_k
      29              :   public :: eval_conv_bdy_r
      30              :   public :: eval_conv_bdy_Hp
      31              :   public :: eval_over_bdy_params
      32              : 
      33              : contains
      34              : 
      35            0 :   subroutine eval_conv_bdy_k (s, i, k, ierr)
      36              : 
      37              :     type(star_info), pointer :: s
      38              :     integer, intent(in)      :: i
      39              :     integer, intent(out)     :: k
      40              :     integer, intent(out)     :: ierr
      41              : 
      42              :     ! Evaluate the index k of the cell containing the i'th convective
      43              :     ! boundary
      44              : 
      45            0 :     ierr = 0
      46              : 
      47            0 :     if (s%top_conv_bdy(i)) then
      48            0 :        k = s%conv_bdy_loc(i)
      49              :     else
      50            0 :        k = s%conv_bdy_loc(i) - 1
      51              :     end if
      52              : 
      53            0 :     if (k >= s%nz .OR. k < 1) then
      54            0 :        write(*,*) 'Invalid cell for convective boundary: i, k, nz=', i, k, s%nz
      55            0 :        ierr = -1
      56            0 :        return
      57              :     end if
      58              : 
      59              :     return
      60              : 
      61              :   end subroutine eval_conv_bdy_k
      62              : 
      63              : 
      64            0 :   subroutine eval_conv_bdy_r (s, i, r, ierr)
      65              : 
      66              :     type(star_info), pointer :: s
      67              :     integer, intent(in)      :: i
      68              :     real(dp), intent(out)    :: r
      69              :     integer, intent(out)     :: ierr
      70              : 
      71              :     integer  :: k
      72              :     real(dp) :: w
      73              : 
      74              :     ! Evaluate the radius r at the i'th convective boundary
      75              : 
      76              :     ! Find the convective boundary cell
      77              : 
      78              :     ierr = 0
      79              : 
      80            0 :     call eval_conv_bdy_k(s, i, k, ierr)
      81            0 :     if (ierr /= 0) return
      82              : 
      83              :     ! Interpolate r based on the fact that r^3 varies linearly with q
      84              :     ! across the (constant-density) cell
      85              : 
      86            0 :     w = s%cz_bdy_dq(k)/s%dq(k)
      87              : 
      88            0 :     if (w < 0._dp .OR. w > 1._dp) then
      89            0 :        write(*,*) 'Invalid weight for convective boundary: i, w=', i, w
      90            0 :        ierr = -1
      91            0 :        return
      92              :     end if
      93              : 
      94              :     associate (k_o => k, &
      95              :                k_i => k+1)
      96              : 
      97              :       r = pow((      w)*s%r(k_i)*s%r(k_i)*s%r(k_i) + &
      98            0 :                  (1._dp-w)*s%r(k_o)*s%r(k_o)*s%r(k_o), 1._dp/3._dp)
      99              : 
     100              :     end associate
     101              : 
     102            0 :     return
     103              : 
     104            0 :   end subroutine eval_conv_bdy_r
     105              : 
     106              : 
     107            0 :   subroutine eval_conv_bdy_Hp (s, i, Hp, ierr)
     108              : 
     109              :     type(star_info), pointer :: s
     110              :     integer, intent(in)      :: i
     111              :     real(dp), intent(out)    :: Hp
     112              :     integer, intent(out)     :: ierr
     113              : 
     114              :     integer  :: k
     115              :     real(dp) :: r
     116            0 :     real(dp) :: x0
     117            0 :     real(dp) :: x1
     118            0 :     real(dp) :: x2
     119            0 :     real(dp) :: x
     120            0 :     real(dp) :: a0
     121            0 :     real(dp) :: a1
     122            0 :     real(dp) :: a2
     123            0 :     real(dp) :: P
     124            0 :     real(dp) :: rho
     125            0 :     real(dp) :: r_top
     126            0 :     real(dp) :: r_bot
     127            0 :     real(dp) :: dr
     128              : 
     129              :     ! Evaluate the pressure scale height Hp at the i'th convective boundary
     130              : 
     131              :     ! Find the convective boundary cell
     132              : 
     133              :     ierr = 0
     134              : 
     135            0 :     call eval_conv_bdy_k(s, i, k, ierr)
     136            0 :     if (ierr /= 0) return
     137              : 
     138              :     ! Evaluate the radius at the convective boundary
     139              : 
     140            0 :     call eval_conv_bdy_r(s, i, r, ierr)
     141            0 :     if (ierr /= 0) return
     142              : 
     143              :     ! Interpolate the pressure and density at the boundary, using a
     144              :     ! quadratic fit across the boundary cell and its neighbors (the
     145              :     ! x's are fractional mass distances from the outer edge of cell
     146              :     ! k-1); then, evaluate the pressure scale height
     147              : 
     148              :     associate (k_o => k-1, &
     149              :                k_m => k, &
     150              :                k_i => k+1)
     151              : 
     152            0 :       x0 = s%dq(k_o)/2._dp
     153            0 :       x1 = s%dq(k_o) + s%dq(k_m)/2._dp
     154            0 :       x2 = s%dq(k_o) + s%dq(k_m) + s%dq(k_i)/2._dp
     155              : 
     156            0 :       x = s%dq(k_o) + s%cz_bdy_dq(k)
     157              : 
     158            0 :       call two_piece_linear_coeffs(x, x0, x1, x2, a0, a1, a2, ierr)
     159            0 :       if (ierr /= 0) return
     160              : 
     161            0 :       P = exp(a0*s%lnPeos(k_o) + a1*s%lnPeos(k_m) + a2*s%lnPeos(k_i))
     162            0 :       rho = exp(a0*s%lnd(k_o) + a1*s%lnd(k_m) + a2*s%lnd(k_i))
     163              : 
     164              :       ! Evaluate the pressure scale height
     165              : 
     166              :       Hp = P/(rho*s%cgrav(k_m)* &
     167            0 :            (s%M_center + s%xmstar*s%conv_bdy_q(i))/(r*r))
     168              : 
     169              :     end associate
     170              : 
     171              :     ! (Possibly) limit the scale height using the size of the
     172              :     ! convection zone
     173              : 
     174            0 :     if (s%limit_overshoot_Hp_using_size_of_convection_zone) then
     175              : 
     176              :        ! Determine the radial extent of the convection zone (note that
     177              :        ! r_top/r_bot don't coincide exactly with the r calculated
     178              :        ! above)
     179              : 
     180            0 :        if (s%top_conv_bdy(i)) then
     181              : 
     182            0 :           if (i == 1) then
     183            0 :              r_bot = s%R_center
     184              :           else
     185            0 :              if (s%top_conv_bdy(i-1)) then
     186            0 :                 write(*,*) 'Double top boundary in overshoot; i=', i
     187            0 :                 ierr = -1
     188            0 :                 return
     189              :              end if
     190            0 :              r_bot = s%r(s%conv_bdy_loc(i-1))
     191              :           end if
     192              : 
     193            0 :           r_top = s%r(k)
     194              : 
     195              :        else
     196              : 
     197            0 :           r_bot = s%r(k+1)
     198              : 
     199            0 :           if (i == s%num_conv_boundaries) then
     200            0 :              r_top = s%r(1)
     201              :           else
     202            0 :              if (.NOT. s%top_conv_bdy(i+1)) then
     203            0 :                 write(*,*) 'Double bottom boundary in overshoot; i=', i
     204            0 :                 ierr = -1
     205            0 :                 return
     206              :              end if
     207            0 :              r_top = s%r(s%conv_bdy_loc(i+1))
     208              :           end if
     209              : 
     210              :        end if
     211              : 
     212            0 :        dr = r_top - r_bot
     213              : 
     214              :        ! Apply the limit
     215              : 
     216            0 :        if (s%overshoot_alpha > 0d0) then
     217            0 :           if (s%overshoot_alpha*Hp > dr) Hp = dr/s%overshoot_alpha
     218              :        else
     219            0 :           if (s%alpha_mlt(k)*Hp > dr) Hp = dr/s%mixing_length_alpha
     220              :        end if
     221              : 
     222              :     end if
     223              : 
     224              :     return
     225              : 
     226            0 :   end subroutine eval_conv_bdy_Hp
     227              : 
     228              : 
     229            0 :   subroutine eval_over_bdy_params (s, i, f0, k, r, D, vc, ierr)
     230              : 
     231              :     type(star_info), pointer :: s
     232              :     integer, intent(in)      :: i
     233              :     real(dp), intent(in)     :: f0
     234              :     integer, intent(out)     :: k
     235              :     real(dp), intent(out)    :: r
     236              :     real(dp), intent(out)    :: D
     237              :     real(dp), intent(out)    :: vc
     238              :     integer, intent(out)     :: ierr
     239              : 
     240              :     integer  :: k_cb
     241              :     real(dp) :: r_cb
     242            0 :     real(dp) :: Hp_cb
     243            0 :     real(dp) :: w
     244            0 :     real(dp) :: lambda
     245              : 
     246              :     ! Evaluate parameters (cell index k, radius r, diffusion
     247              :     ! coefficients D and cdc) for the overshoot boundary associated
     248              :     ! with the i'th convective boundary
     249              : 
     250              :     ! Find the convective boundary cell
     251              : 
     252              :     ierr = 0
     253              : 
     254            0 :     call eval_conv_bdy_k(s, i, k_cb, ierr)
     255            0 :     if (ierr /= 0) return
     256              : 
     257              :     ! Evaluate the radius at the convective boundary
     258              : 
     259            0 :     call eval_conv_bdy_r(s, i, r_cb, ierr)
     260            0 :     if (ierr /= 0) return
     261              : 
     262              :     ! Evaluate the pressure scale height at the convective boundary
     263              : 
     264            0 :     call eval_conv_bdy_Hp(s, i, Hp_cb, ierr)
     265            0 :     if (ierr /= 0) return
     266              : 
     267              :     ! Search for the overshoot boundary cell
     268              : 
     269            0 :     ierr = 0
     270              : 
     271            0 :     if (s%top_conv_bdy(i)) then
     272              : 
     273              :        ! Overshooting outward -- search inward
     274              : 
     275            0 :        r = r_cb - f0*Hp_cb
     276              : 
     277            0 :        if (r <= s%r(s%nz)) then
     278              : 
     279            0 :           r = s%r(s%nz)
     280            0 :           k = s%nz - 1
     281              : 
     282              :        else
     283              : 
     284            0 :           search_in_loop: do k = k_cb, s%nz-1
     285            0 :              if (s%r(k+1) <= r) exit search_in_loop
     286              :           end do search_in_loop
     287              : 
     288              :        end if
     289              : 
     290              :     else
     291              : 
     292              :        ! Overshooting inward -- search outward
     293              : 
     294            0 :        r = r_cb + f0*Hp_cb
     295              : 
     296            0 :        if (r >=  s%r(1)) then
     297              : 
     298            0 :           r = s%r(1)
     299            0 :           k = 1
     300              : 
     301              :        else
     302              : 
     303            0 :           search_out_loop : do k = k_cb, 1, -1
     304            0 :              if (s%r(k) > r) exit search_out_loop
     305              :           end do search_out_loop
     306              : 
     307              :        end if
     308              : 
     309              :     end if
     310              : 
     311            0 :     if (.NOT. (s%r(k+1) <= r .AND. s%r(k) >= r)) then
     312            0 :        write(*,*) 'r_ob not correctly bracketed: r(k+1), r, r(k)=', s%r(k+1), r, s%r(k)
     313            0 :        ierr = -1
     314            0 :        return
     315              :     end if
     316              : 
     317              :     ! Interpolate mixing parameters
     318              : 
     319              :     w = (s%r(k)*s%r(k)*s%r(k) - r*r*r)/ &
     320            0 :         (s%r(k)*s%r(k)*s%r(k) - s%r(k+1)*s%r(k+1)*s%r(k+1))
     321              : 
     322            0 :     lambda = (1._dp-w)*s%mlt_mixing_length(k) + w*s%mlt_mixing_length(k+1)
     323              : 
     324            0 :     if (s%conv_vel(k) /= 0._dp .AND. s%conv_vel(k+1) /= 0._dp) then
     325              : 
     326              :        ! Both faces of cell have non-zero mixing; interpolate vc between faces
     327              : 
     328            0 :        vc = (1._dp-w)*s%conv_vel(k) + w*s%conv_vel(k+1)
     329              : 
     330            0 :     elseif (s%conv_vel(k) /= 0._dp .AND. s%conv_vel(k+1) == 0._dp) then
     331              : 
     332              :        ! Outer face of cell has non-zero mixing; interpolate vc
     333              :        ! between this face and r_cb, assuming vc = 0 at the latter
     334              : 
     335            0 :         if(s%r(k) /= r_cb) then
     336              :           w = (s%r(k)*s%r(k)*s%r(k) - r*r*r)/ &
     337            0 :            (s%r(k)*s%r(k)*s%r(k) - r_cb*r_cb*r_cb)
     338              :         else
     339              :           w = 0d0
     340              :         end if
     341              : 
     342            0 :        vc = (1._dp-w)*s%conv_vel(k)
     343              : 
     344            0 :     elseif (s%conv_vel(k) == 0._dp .AND. s%conv_vel(k+1) /= 0._dp) then
     345              : 
     346              :        ! Inner face of cell has non-zero mixing; interpolate vc
     347              :        ! between this face and r_cb, assuming vc = 0 at the latter
     348              : 
     349            0 :        if(s%r(k+1) /= r_cb) then
     350              :           w = (r_cb*r_cb*r_cb - r*r*r)/ &
     351            0 :            (r_cb*r_cb*r_cb - s%r(k+1)*s%r(k+1)*s%r(k+1))
     352              :        else
     353              :           w = 0d0
     354              :        end if
     355              : 
     356            0 :        vc = w*s%conv_vel(k+1)
     357              : 
     358              :     else
     359              : 
     360              :        ! Neither face of cell has non-zero mixing; return
     361              : 
     362            0 :        vc = 0._dp
     363              : 
     364              :     end if
     365              : 
     366              :     ! Evaluate the diffusion coefficient
     367              : 
     368            0 :     D = vc*lambda/3._dp
     369              : 
     370              :     ierr = 0
     371              : 
     372            0 :     return
     373              : 
     374              :   end subroutine eval_over_bdy_params
     375              : 
     376              : end module overshoot_utils
        

Generated by: LCOV version 2.0-1