LCOV - code coverage report
Current view: top level - star/private - hydro_rsp2.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 563 0
Test Date: 2026-08-20 21:51:39 Functions: 0.0 % 34 0

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2020  The MESA Team
       4              : !
       5              : !   This program is free software: you can redistribute it and/or modify
       6              : !   it under the terms of the GNU Lesser General Public License
       7              : !   as published by the Free Software Foundation,
       8              : !   either version 3 of the License, or (at your option) any later version.
       9              : !
      10              : !   This program is distributed in the hope that it will be useful,
      11              : !   but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              : !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13              : !   See the GNU Lesser General Public License for more details.
      14              : !
      15              : !   You should have received a copy of the GNU Lesser General Public License
      16              : !   along with this program. If not, see <https://www.gnu.org/licenses/>.
      17              : !
      18              : ! ***********************************************************************
      19              : 
      20              :       module hydro_rsp2
      21              : 
      22              :       use star_private_def
      23              :       use const_def, only: dp, boltz_sigma, pi, clight, crad, ln10
      24              :       use utils_lib, only: is_bad
      25              :       use auto_diff
      26              :       use auto_diff_support
      27              :       use accurate_sum_auto_diff_star_order1
      28              :       use star_utils
      29              : 
      30              :       implicit none
      31              : 
      32              :       private
      33              :       public :: do1_rsp2_L_eqn
      34              :       public :: do1_turbulent_energy_eqn
      35              :       public :: do1_rsp2_Hp_eqn
      36              :       public :: compute_Eq_cell
      37              :       public :: compute_Uq_face
      38              :       public :: set_RSP2_vars
      39              :       public :: Hp_face_for_rsp2_val
      40              :       public :: Hp_face_for_rsp2_eqn, set_etrb_start_vars
      41              :       public :: RSP2_adjust_vars_before_call_solver
      42              :       public :: get_RSP2_alfa_beta_face_weights
      43              : 
      44              :       real(dp), parameter :: &
      45              :          x_ALFAP = 2.d0/3.d0, &  ! Ptrb
      46              :          x_ALFAS = (1.d0/2.d0)*sqrt_2_div_3, &  ! PII_face and Lc
      47              :          x_ALFAC = (1.d0/2.d0)*sqrt_2_div_3, &  ! Lc
      48              :          x_CEDE  = (8.d0/3.d0)*sqrt_2_div_3, &  ! DAMP
      49              :          x_GAMMAR = 2.d0*sqrt(3.d0)  ! DAMPR
      50              : 
      51              :       contains
      52              : 
      53            0 :       subroutine set_RSP2_vars(s,ierr)
      54              :          type (star_info), pointer :: s
      55              :          integer, intent(out) :: ierr
      56              :          type(auto_diff_real_star_order1) :: x
      57              :          integer :: k, op_err
      58              :          include 'formats'
      59            0 :          ierr = 0
      60            0 :          op_err = 0
      61            0 :          !$OMP PARALLEL DO PRIVATE(k,op_err) SCHEDULE(dynamic,2)
      62              :          do k=1,s%nz
      63              :             ! Hp_face(k) <= 0 means it needs to be set.  e.g., after read file
      64              :             if (s% Hp_face(k) <= 0) then
      65              :                s% Hp_face(k) = get_scale_height_face_val(s,k)
      66              :                s% xh(s% i_Hp,k) = s% Hp_face(k)
      67              :             end if
      68              :             x = compute_Y_face(s, k, op_err)
      69              :             if (op_err /= 0) ierr = op_err
      70              :             x = compute_PII_face(s, k, op_err)
      71              :             if (op_err /= 0) ierr = op_err
      72              :             !Pvsc           skip?
      73              :          end do
      74              :          !$OMP END PARALLEL DO
      75            0 :          if (ierr /= 0) then
      76            0 :             if (s% report_ierr) write(*,2) 'failed in set_RSP2_vars loop 1', s% model_number
      77            0 :             return
      78              :          end if
      79            0 :          !$OMP PARALLEL DO PRIVATE(k,op_err) SCHEDULE(dynamic,2)
      80              :          do k=1,s% nz
      81              :             x = compute_Chi_cell(s, k, op_err)
      82              :             if (op_err /= 0) ierr = op_err
      83              :             x = compute_Eq_cell(s, k, op_err)
      84              :             if (op_err /= 0) ierr = op_err
      85              :             x = compute_C(s, k, op_err)  ! COUPL
      86              :             if (op_err /= 0) ierr = op_err
      87              :             x = compute_L_face(s, k, op_err)  ! Lr, Lt, Lc
      88              :             if (op_err /= 0) ierr = op_err
      89              :          end do
      90              :          !$OMP END PARALLEL DO
      91            0 :          if (ierr /= 0) then
      92            0 :             if (s% report_ierr) write(*,2) 'failed in set_RSP2_vars loop 2', s% model_number
      93            0 :             return
      94              :          end if
      95            0 :          do k = 1, s% RSP2_num_outermost_cells_forced_nonturbulent
      96            0 :             s% Eq(k) = 0d0; s% Eq_ad(k) = 0d0
      97            0 :             s% Chi(k) = 0d0; s% Chi_ad(k) = 0d0
      98            0 :             s% COUPL(k) = 0d0; s% COUPL_ad(k) = 0d0
      99              :             !s% Ptrb(k) = 0d0;
     100            0 :             s% Lc(k) = 0d0; s% Lc_ad(k) = 0d0
     101            0 :             s% Lt(k) = 0d0; s% Lt_ad(k) = 0d0
     102              :          end do
     103            0 :          do k = s% nz + 1 - int(s% nz/s% RSP2_nz_div_IBOTOM) , s% nz
     104            0 :             s% Eq(k) = 0d0; s% Eq_ad(k) = 0d0
     105            0 :             s% Chi(k) = 0d0; s% Chi_ad(k) = 0d0
     106            0 :             s% COUPL(k) = 0d0; s% COUPL_ad(k) = 0d0
     107              :             !s% Ptrb(k) = 0d0;
     108            0 :             s% Lc(k) = 0d0; s% Lc_ad(k) = 0d0
     109            0 :             s% Lt(k) = 0d0; s% Lt_ad(k) = 0d0
     110              :          end do
     111              :       end subroutine set_RSP2_vars
     112              : 
     113              : 
     114            0 :       subroutine do1_rsp2_L_eqn(s, k, nvar, ierr)
     115              :          use star_utils, only: save_eqn_residual_info
     116              :          type (star_info), pointer :: s
     117              :          integer, intent(in) :: k, nvar
     118              :          integer, intent(out) :: ierr
     119              :          type(auto_diff_real_star_order1) ::  &
     120              :             L_expected, L_actual,resid
     121              :          type(accurate_auto_diff_real_star_order1) :: L_sum
     122              :          real(dp) :: scale, residual, L_start_max
     123              :          logical :: test_partials
     124              :          include 'formats'
     125              : 
     126              :          !test_partials = (k == s% solver_test_partials_k)
     127            0 :          test_partials = .false.
     128            0 :          if (.not. s% RSP2_flag) then
     129            0 :             ierr = -1
     130            0 :             return
     131              :          end if
     132              : 
     133            0 :          ierr = 0
     134              :          !L_expected = compute_L_face(s, k, ierr)
     135              :          !if (ierr /= 0) return
     136            0 :          L_sum = s% Lr_ad(k)
     137            0 :          L_sum = L_sum + s% Lc_ad(k)
     138            0 :          L_sum = L_sum + s% Lt_ad(k)
     139            0 :          L_expected = L_sum
     140            0 :          L_actual = wrap_L_00(s, k)
     141            0 :          L_start_max = maxval(s% L_start(1:s% nz))
     142            0 :          scale = 1d0/L_start_max
     143            0 :          if (is_bad(scale)) then
     144            0 :             write(*,2) 'do1_rsp2_L_eqn scale', k, scale
     145            0 :             call mesa_error(__FILE__,__LINE__,'do1_rsp2_L_eqn')
     146              :          end if
     147            0 :          resid = (L_expected - L_actual)*scale
     148              : 
     149            0 :          residual = resid%val
     150            0 :          s% equ(s% i_equL, k) = residual
     151              :          if (test_partials) then
     152              :             s% solver_test_partials_val = residual
     153              :          end if
     154              : 
     155            0 :          call save_eqn_residual_info(s, k, nvar, s% i_equL, resid, 'do1_rsp2_L_eqn', ierr)
     156            0 :          if (ierr /= 0) return
     157              : 
     158              :          if (test_partials) then
     159              :             s% solver_test_partials_var = s% i_lnR
     160              :             s% solver_test_partials_dval_dx = resid%d1Array(i_lnR_00)
     161              :             write(*,4) 'do1_rsp2_L_eqn', s% solver_test_partials_var
     162              :          end if
     163              :       end subroutine do1_rsp2_L_eqn
     164              : 
     165              : 
     166            0 :       subroutine do1_rsp2_Hp_eqn(s, k, nvar, ierr)
     167              :          use star_utils, only: save_eqn_residual_info
     168              :          type (star_info), pointer :: s
     169              :          integer, intent(in) :: k, nvar
     170              :          integer, intent(out) :: ierr
     171              :          type(auto_diff_real_star_order1) ::  &
     172              :             Hp_expected, Hp_actual,resid
     173              :          real(dp) :: residual, Hp_start
     174              :          logical :: test_partials
     175              :          include 'formats'
     176              :          !test_partials = (k == s% solver_test_partials_k)
     177            0 :          test_partials = .false.
     178              : 
     179            0 :          if (.not. s% RSP2_flag) then
     180            0 :             ierr = -1
     181            0 :             return
     182              :          end if
     183              : 
     184              :          ierr = 0
     185            0 :          Hp_expected = Hp_face_for_rsp2_eqn(s, k, ierr)
     186            0 :          if (ierr /= 0) return
     187            0 :          Hp_actual = wrap_Hp_00(s, k)
     188            0 :          Hp_start = s% Hp_face_start(k)
     189            0 :          resid = (Hp_expected - Hp_actual)/max(Hp_expected,Hp_actual)
     190              : 
     191            0 :          residual = resid%val
     192            0 :          s% equ(s% i_equ_Hp, k) = residual
     193              :          if (test_partials) then
     194              :             s% solver_test_partials_val = residual
     195              :          end if
     196              : 
     197            0 :          if (residual > 1d3) then
     198            0 :          !$omp critical (hydro_rsp2_1)
     199            0 :             write(*,2) 'residual', k, residual
     200            0 :             write(*,2) 'Hp_expected', k, Hp_expected%val
     201            0 :             write(*,2) 'Hp_actual', k, Hp_actual%val
     202            0 :             call mesa_error(__FILE__,__LINE__,'do1_rsp2_Hp_eqn')
     203              :          !$omp end critical (hydro_rsp2_1)
     204              :          end if
     205              : 
     206            0 :          call save_eqn_residual_info(s, k, nvar, s% i_equ_Hp, resid, 'do1_rsp2_Hp_eqn', ierr)
     207            0 :          if (ierr /= 0) return
     208              : 
     209              :          if (test_partials) then
     210              :             s% solver_test_partials_var = s% i_lnR
     211              :             s% solver_test_partials_dval_dx = resid%d1Array(i_lnR_00)
     212              :             write(*,4) 'do1_rsp2_Hp_eqn', s% solver_test_partials_var
     213              :          end if
     214              : 
     215              :       end subroutine do1_rsp2_Hp_eqn
     216              : 
     217              : 
     218            0 :       real(dp) function Hp_face_for_rsp2_val(s, k, ierr) result(Hp_face)  ! cm
     219              :          type (star_info), pointer :: s
     220              :          integer, intent(in) :: k
     221              :          integer, intent(out) :: ierr
     222              :          type(auto_diff_real_star_order1) :: Hp_face_ad
     223              :          ierr = 0
     224            0 :          Hp_face_ad = Hp_face_for_rsp2_eqn(s, k, ierr)
     225            0 :          if (ierr /= 0) return
     226            0 :          Hp_face = Hp_face_ad%val
     227            0 :       end function Hp_face_for_rsp2_val
     228              : 
     229              : 
     230            0 :       function Hp_face_for_rsp2_eqn(s, k, ierr) result(Hp_face)  ! cm
     231              :          type (star_info), pointer :: s
     232              :          integer, intent(in) :: k
     233              :          integer, intent(out) :: ierr
     234              :          type(auto_diff_real_star_order1) :: Hp_face
     235              :          type(auto_diff_real_star_order1) :: &
     236              :             rho_face, area, dlnPeos, &
     237              :             r_00, Peos_00, d_00, Peos_m1, d_m1, Peos_div_rho, &
     238              :             d_face, Peos_face, alt_Hp_face, A
     239              :          real(dp) :: alfa, beta
     240              :          include 'formats'
     241            0 :          ierr = 0
     242            0 :          if (k > s% nz) then
     243            0 :             Hp_face = 1d0  ! not used
     244            0 :             return
     245              :          end if
     246            0 :          if (k > 1 .and. .not. s% RSP2_assume_HSE) then
     247            0 :             call get_RSP2_alfa_beta_face_weights(s, k, alfa, beta)
     248            0 :             rho_face = alfa*wrap_d_00(s,k) + beta*wrap_d_m1(s,k)
     249            0 :             area = 4d0*pi*pow2(wrap_r_00(s,k))
     250            0 :             dlnPeos = wrap_lnPeos_m1(s,k) - wrap_lnPeos_00(s,k)
     251            0 :             Hp_face = -s% dm_bar(k)/(area*rho_face*dlnPeos)
     252              :          else
     253            0 :             r_00 = wrap_r_00(s, k)  ! not time-centered in RSP
     254            0 :             d_00 = wrap_d_00(s, k)
     255            0 :             Peos_00 = wrap_Peos_00(s, k)
     256            0 :             if (k == 1) then
     257            0 :                Peos_div_rho = Peos_00/d_00
     258            0 :                Hp_face = pow2(r_00)*Peos_div_rho/(s% cgrav(k)*s% m(k))
     259              :             else
     260            0 :                d_m1 = wrap_d_m1(s, k)
     261            0 :                Peos_m1 = wrap_Peos_m1(s, k)
     262            0 :                call get_RSP2_alfa_beta_face_weights(s, k, alfa, beta)
     263            0 :                Peos_div_rho = alfa*Peos_00/d_00 + beta*Peos_m1/d_m1
     264            0 :                Hp_face = pow2(r_00)*Peos_div_rho/(s% cgrav(k)*s% m(k))
     265            0 :                if (k==-104) then
     266            0 :                   write(*,3) 'RSP2 Hp P_div_rho Pdrho_00 Pdrho_m1', k, s% solver_iter, &
     267            0 :                      Hp_face%val, Peos_div_rho%val, Peos_00%val/d_00%val, Peos_m1%val/d_m1%val
     268              :                   !write(*,3) 'RSP2 Hp r2_div_Gm r_start r', k, s% solver_iter, &
     269              :                   !   Hp_face%val, pow2(r_00%val)/(s% cgrav(k)*s% m(k)), &
     270              :                   !   s% r_start(k), r_00%val
     271              :                end if
     272            0 :                if (s% alt_scale_height_flag) then
     273            0 :                   call mesa_error(__FILE__,__LINE__,'Hp_face_for_rsp2_eqn: cannot use alt_scale_height_flag')
     274              :                   ! consider sound speed*hydro time scale as an alternative scale height
     275              :                   d_face = alfa*d_00 + beta*d_m1
     276              :                   Peos_face = alfa*Peos_00 + beta*Peos_m1
     277              :                   alt_Hp_face = sqrt(Peos_face/s% cgrav(k))/d_face
     278              :                   if (alt_Hp_face%val < Hp_face%val) then  ! blend
     279              :                      A = pow2(alt_Hp_face/Hp_face)  ! 0 <= A%val < 1
     280              :                      Hp_face = A*Hp_face + (1d0 - A)*alt_Hp_face
     281              :                   end if
     282              :                end if
     283              :             end if
     284              :          end if
     285            0 :       end function Hp_face_for_rsp2_eqn
     286              : 
     287              : 
     288            0 :       subroutine do1_turbulent_energy_eqn(s, k, nvar, ierr)
     289              :          use star_utils, only: set_energy_eqn_scal, save_eqn_residual_info
     290              :          type (star_info), pointer :: s
     291              :          integer, intent(in) :: k, nvar
     292              :          integer, intent(out) :: ierr
     293              :          ! for OLD WAY
     294              :          type(auto_diff_real_star_order1) :: &
     295              :             d_turbulent_energy_ad, Ptrb_dV_ad, dt_C_ad, dt_Eq_ad
     296              :          type(auto_diff_real_star_order1) :: w_00
     297              :          type(auto_diff_real_star_order1) :: tst, resid_ad, dt_dLt_dm_ad
     298              :          type(accurate_auto_diff_real_star_order1) :: esum_ad
     299              :          logical :: non_turbulent_cell, test_partials
     300              :          real(dp) :: residual, scal
     301              :          include 'formats'
     302              :          !test_partials = (k == s% solver_test_partials_k)
     303            0 :          test_partials = .false.
     304              : 
     305            0 :          ierr = 0
     306            0 :          w_00 = wrap_w_00(s,k)
     307              : 
     308              :          non_turbulent_cell = &
     309              :             s% mixing_length_alpha == 0d0 .or. &
     310              :             k <= s% RSP2_num_outermost_cells_forced_nonturbulent .or. &
     311            0 :             k > s% nz - int(s% nz/s% RSP2_nz_div_IBOTOM)
     312            0 :          if (.not. s% RSP2_flag) then
     313            0 :             resid_ad = w_00 - s% w_start(k)  ! just hold w constant when not using RSP2
     314            0 :          else if (non_turbulent_cell) then
     315            0 :             resid_ad = w_00/s% csound(k)  ! make w = 0
     316              :          else
     317            0 :             call setup_d_turbulent_energy(ierr); if (ierr /= 0) return  ! erg g^-1 = cm^2 s^-2
     318            0 :             call setup_Ptrb_dV_ad(ierr); if (ierr /= 0) return  ! erg g^-1
     319            0 :             call setup_dt_dLt_dm_ad(ierr); if (ierr /= 0) return  ! erg g^-1
     320            0 :             call setup_dt_C_ad(ierr); if (ierr /= 0) return  ! erg g^-1
     321            0 :             call setup_dt_Eq_ad(ierr); if (ierr /= 0) return  ! erg g^-1
     322            0 :             call set_energy_eqn_scal(s, k, scal, ierr); if (ierr /= 0) return  ! 1/(erg g^-1 s^-1)
     323              :             ! sum terms in esum_ad using accurate_auto_diff_real_star_order1
     324            0 :             esum_ad = d_turbulent_energy_ad
     325            0 :             esum_ad = esum_ad + Ptrb_dV_ad
     326            0 :             esum_ad = esum_ad + dt_dLt_dm_ad
     327            0 :             esum_ad = esum_ad - dt_C_ad
     328            0 :             esum_ad = esum_ad - dt_Eq_ad  ! erg g^-1
     329            0 :             resid_ad = esum_ad
     330              : 
     331            0 :             if (k==-35 .and. s% solver_iter == 1) then
     332            0 :                   write(*,3) 'RSP2 w dEt PdV dtC dtEq', k, s% solver_iter, &
     333            0 :                      w_00%val, d_turbulent_energy_ad%val, Ptrb_dV_ad%val, dt_C_ad%val, dt_Eq_ad%val
     334              :             end if
     335              : 
     336            0 :             resid_ad = resid_ad*scal/s%dt  ! to make residual unitless, must cancel out the dt in scal
     337              : 
     338              :          end if
     339              : 
     340            0 :          residual = resid_ad%val
     341            0 :          s% equ(s% i_detrb_dt, k) = residual
     342              : 
     343              :          if (test_partials) then
     344              :             tst = residual
     345              :             s% solver_test_partials_val = tst%val
     346              :             if (s% solver_iter == 12) &
     347              :                write(*,*) 'do1_turbulent_energy_eqn', s% solver_test_partials_var, s% lnd(k), tst%val
     348              :          end if
     349              : 
     350            0 :          call save_eqn_residual_info(s, k, nvar, s% i_detrb_dt, resid_ad, 'do1_turbulent_energy_eqn', ierr)
     351            0 :          if (ierr /= 0) return
     352              : 
     353              :          if (test_partials) then
     354              :             s% solver_test_partials_var = s% i_lnd
     355              :             s% solver_test_partials_dval_dx = tst%d1Array(i_lnd_00)     ! xi0 good , xi1 partial 0, xi2 good.  Af horrible.'
     356              :             write(*,*) 'do1_turbulent_energy_eqn', s% solver_test_partials_var, s% lnd(k)/ln10, tst%val
     357              :          end if
     358              : 
     359              :          contains
     360              : 
     361            0 :          subroutine setup_d_turbulent_energy(ierr)  ! erg g^-1
     362              :             integer, intent(out) :: ierr
     363            0 :             ierr = 0
     364            0 :             d_turbulent_energy_ad = wrap_etrb_00(s,k) - get_etrb_start(s,k)
     365            0 :          end subroutine setup_d_turbulent_energy
     366              : 
     367              :          ! Ptrb_dV_ad = Ptrb_ad*dV_ad
     368            0 :          subroutine setup_Ptrb_dV_ad(ierr)  ! erg g^-1
     369              :             use star_utils, only: calc_Ptrb_ad_tw
     370              :             integer, intent(out) :: ierr
     371              :             type(auto_diff_real_star_order1) :: Ptrb_ad, PT0, dV_ad, d_00
     372            0 :             call calc_Ptrb_ad_tw(s, k, Ptrb_ad, PT0, ierr)
     373            0 :             if (ierr /= 0) return
     374            0 :             d_00 = wrap_d_00(s,k)
     375            0 :             dV_ad = 1d0/d_00 - 1d0/s% rho_start(k)
     376            0 :             Ptrb_dV_ad = Ptrb_ad*dV_ad  ! erg cm^-3 cm^-3 g^-1 = erg g^-1
     377              :          end subroutine setup_Ptrb_dV_ad
     378              : 
     379            0 :          subroutine setup_dt_dLt_dm_ad(ierr)  ! erg g^-1
     380              :             integer, intent(out) :: ierr
     381              :             type(auto_diff_real_star_order1) :: Lt_00, Lt_p1
     382              :             real(dp) :: L_theta
     383              :             include 'formats'
     384            0 :             ierr = 0
     385            0 :             if (s% using_velocity_time_centering .and. &
     386              :                      s% include_L_in_velocity_time_centering) then
     387            0 :                L_theta = s% L_theta_for_velocity_time_centering
     388              :             else
     389            0 :                L_theta = 1d0
     390              :             end if
     391            0 :             Lt_00 = L_theta*s% Lt_ad(k) + (1d0 - L_theta)*s% Lt_start(k)
     392            0 :             if (k == s% nz) then
     393            0 :                Lt_p1 = 0d0
     394              :             else
     395            0 :                Lt_p1 = L_theta*shift_p1(s% Lt_ad(k+1)) + (1d0 - L_theta)*s% Lt_start(k+1)
     396            0 :                if (ierr /= 0) return
     397              :             end if
     398            0 :             dt_dLt_dm_ad = (Lt_00 - Lt_p1)*s%dt/s%dm(k)
     399              :          end subroutine setup_dt_dLt_dm_ad
     400              : 
     401            0 :          subroutine setup_dt_C_ad(ierr)  ! erg g^-1
     402              :             integer, intent(out) :: ierr
     403              :             type(auto_diff_real_star_order1) :: C
     404            0 :             C = s% COUPL_ad(k)  ! compute_C(s, k, ierr) ! erg g^-1 s^-1
     405            0 :             if (ierr /= 0) return
     406            0 :             dt_C_ad = s%dt*C
     407              :          end subroutine setup_dt_C_ad
     408              : 
     409            0 :          subroutine setup_dt_Eq_ad(ierr)  ! erg g^-1
     410              :             integer, intent(out) :: ierr
     411              :             type(auto_diff_real_star_order1) :: Eq_cell
     412            0 :             Eq_cell = s% Eq_ad(k)  ! compute_Eq_cell(s, k, ierr) ! erg g^-1 s^-1
     413            0 :             if (ierr /= 0) return
     414            0 :             dt_Eq_ad = s%dt*Eq_cell
     415              :          end subroutine setup_dt_Eq_ad
     416              : 
     417              :       end subroutine do1_turbulent_energy_eqn
     418              : 
     419              : 
     420            0 :       subroutine get_RSP2_alfa_beta_face_weights(s, k, alfa, beta)
     421              :          type (star_info), pointer :: s
     422              :          integer, intent(in) :: k
     423              :          real(dp), intent(out) :: alfa, beta
     424              :          ! face_value = alfa*cell_value(k) + beta*cell_value(k-1)
     425            0 :          if (k == 1) call mesa_error(__FILE__,__LINE__,'bad k==1 for get_RSP2_alfa_beta_face_weights')
     426            0 :          if (s% RSP2_use_mass_interp_face_values) then
     427            0 :             alfa = s% dq(k-1)/(s% dq(k-1) + s% dq(k))
     428            0 :             beta = 1d0 - alfa
     429              :          else
     430            0 :             alfa = 0.5d0
     431            0 :             beta = 0.5d0
     432              :          end if
     433            0 :       end subroutine get_RSP2_alfa_beta_face_weights
     434              : 
     435              : 
     436            0 :       function compute_Y_face(s, k, ierr) result(Y_face)  ! superadiabatic gradient [unitless]
     437              :          type (star_info), pointer :: s
     438              :          integer, intent(in) :: k
     439              :          integer, intent(out) :: ierr
     440              :          type(auto_diff_real_star_order1) :: Y_face
     441              :          type(auto_diff_real_star_order1) :: Hp_face, Y1, Y2, QQ_div_Cp_face, &
     442              :             r_00, d_00, Peos_00, Cp_00, T_00, chiT_00, chiRho_00, QQ_00, lnT_00, &
     443              :             r_m1, d_m1, Peos_m1, Cp_m1, T_m1, chiT_m1, chiRho_m1, QQ_m1, lnT_m1, &
     444              :             dlnT_dlnP, grad_ad_00, grad_ad_m1, grad_ad_face, dlnT, dlnP, alt_Y_face
     445              :          real(dp) :: dm_bar, alfa, beta
     446              :          include 'formats'
     447            0 :          ierr = 0
     448              : 
     449            0 :          if (k > s% nz) then
     450            0 :             Y_face = 0d0
     451            0 :             return
     452              :          end if
     453              : 
     454            0 :          if (k == 1 .or. s% mixing_length_alpha == 0d0) then
     455            0 :             Y_face = 0d0
     456            0 :             s% Y_face(k) = 0d0
     457            0 :             s% Y_face_ad(k) = 0d0
     458            0 :             return
     459              :          end if
     460              : 
     461            0 :          call get_RSP2_alfa_beta_face_weights(s, k, alfa, beta)
     462              : 
     463            0 :          if (s% RSP2_use_RSP_eqn_for_Y_face) then
     464              : 
     465            0 :             dm_bar = s% dm_bar(k)
     466            0 :             Hp_face = wrap_Hp_00(s,k)
     467            0 :             r_00 = wrap_r_00(s, k)
     468            0 :             d_00 = wrap_d_00(s, k)
     469            0 :             Peos_00 = wrap_Peos_00(s, k)
     470            0 :             Cp_00 = wrap_Cp_00(s, k)
     471            0 :             T_00 = wrap_T_00(s, k)
     472            0 :             chiT_00 = wrap_chiT_00(s, k)
     473            0 :             chiRho_00 = wrap_chiRho_00(s, k)
     474            0 :             QQ_00 = chiT_00/(d_00*T_00*chiRho_00)
     475            0 :             lnT_00 = wrap_lnT_00(s,k)
     476              : 
     477            0 :             r_m1 = wrap_r_m1(s, k)
     478            0 :             d_m1 = wrap_d_m1(s, k)
     479            0 :             Peos_m1 = wrap_Peos_m1(s, k)
     480            0 :             Cp_m1 = wrap_Cp_m1(s, k)
     481            0 :             T_m1 = wrap_T_m1(s, k)
     482            0 :             chiT_m1 = wrap_chiT_m1(s, k)
     483            0 :             chiRho_m1 = wrap_chiRho_m1(s, k)
     484            0 :             QQ_m1 = chiT_m1/(d_m1*T_m1*chiRho_m1)
     485            0 :             lnT_m1 = wrap_lnT_m1(s,k)
     486            0 :             QQ_div_Cp_face = alfa*QQ_00/Cp_00 + beta*QQ_m1/Cp_m1
     487              :             ! QQ units (g cm^-3 K)^-1 = g^-1 cm^3 K^-1
     488              :             ! Cp units erg g^-1 K^-1 = g cm^2 s^-2 g^-1 K^-1 = cm^2 s^-2 K^-1
     489              :             ! QQ/Cp units = (g^-1 cm^3 K^-1)/(cm^2 s^-2 K^-1)
     490              :             !  = g^-1 cm^3 K^-1 cm^-2 s^2 K
     491              :             !  = g^-1 cm s^2
     492              :             ! P units = erg cm^-3 = g cm^2 s^-2 cm^-3 = g cm^-1 s^-2
     493              :             ! QQ/Cp*P is unitless.
     494              : 
     495            0 :             Y1 = QQ_div_Cp_face*(Peos_m1 - Peos_00) - (lnT_m1 - lnT_00)
     496              :             ! Y1 unitless
     497              : 
     498            0 :             Y2 = 4d0*pi*pow2(r_00)*Hp_face*2d0/(1d0/d_00 + 1d0/d_m1)/dm_bar
     499              :             ! units = cm^2 cm / (cm^3 g^-1) / g
     500              :             !       = cm^2 cm cm^-3 g g^-1 = unitless
     501              : 
     502            0 :             Y_face = Y1*Y2  ! unitless
     503              : 
     504            0 :             if (k==-35) then
     505            0 :                write(*,3) 'RSP2 Y_face Y1 Y2', k, s% solver_iter, s% Y_face(k), Y1%val, Y2%val
     506            0 :                write(*,3) 'Peos', k, s% solver_iter, Peos_00%val
     507            0 :                write(*,3) 'Peos', k-1, s% solver_iter, Peos_m1%val
     508            0 :                write(*,3) 'QQ', k, s% solver_iter, QQ_00%val
     509            0 :                write(*,3) 'QQ', k-1, s% solver_iter, QQ_m1%val
     510            0 :                write(*,3) 'Cp', k, s% solver_iter, Cp_00%val
     511            0 :                write(*,3) 'Cp', k-1, s% solver_iter, Cp_m1%val
     512            0 :                write(*,3) 'lgT', k, s% solver_iter, lnT_00%val/ln10
     513            0 :                write(*,3) 'lgT', k-1, s% solver_iter, lnT_m1%val/ln10
     514            0 :                write(*,3) 'lgd', k, s% solver_iter, s% lnd(k)/ln10
     515            0 :                write(*,3) 'lgd', k-1, s% solver_iter, s% lnd(k-1)/ln10
     516              :                !call mesa_error(__FILE__,__LINE__,'compute_Y_face')
     517              :             end if
     518              : 
     519              :          else
     520              : 
     521            0 :             grad_ad_00 = wrap_grad_ad_00(s,k)
     522            0 :             grad_ad_m1 = wrap_grad_ad_m1(s,k)
     523            0 :             grad_ad_face = alfa*grad_ad_00 + beta*grad_ad_m1
     524            0 :             dlnT = wrap_lnT_m1(s,k) - wrap_lnT_00(s,k)
     525            0 :             dlnP = wrap_lnPeos_m1(s,k) - wrap_lnPeos_00(s,k)
     526            0 :             dlnT_dlnP = dlnT/dlnP
     527            0 :             if (is_bad(dlnT_dlnP%val)) then
     528            0 :                alt_Y_face = 0d0
     529            0 :             else if (s% use_Ledoux_criterion .and. s% calculate_Brunt_B) then
     530              :                ! gradL = grada + gradL_composition_term
     531            0 :                alt_Y_face = dlnT_dlnP - (grad_ad_face + s% gradL_composition_term(k))
     532              :             else
     533            0 :                alt_Y_face = dlnT_dlnP - grad_ad_face
     534              :             end if
     535            0 :             if (is_bad(alt_Y_face%val)) alt_Y_face = 0
     536            0 :             Y_face = alt_Y_face
     537              : 
     538              :          end if
     539              : 
     540            0 :          s% Y_face_ad(k) = Y_face
     541            0 :          s% Y_face(k) = Y_face%val
     542              : 
     543            0 :       end function compute_Y_face
     544              : 
     545              : 
     546            0 :       function compute_PII_face(s, k, ierr) result(PII_face)  ! ergs g^-1 K^-1 (like Cp)
     547              :          type (star_info), pointer :: s
     548              :          integer, intent(in) :: k
     549              :          type(auto_diff_real_star_order1) :: PII_face
     550              :          integer, intent(out) :: ierr
     551              :          type(auto_diff_real_star_order1) :: Cp_00, Cp_m1, Cp_face, Y_face, T_00, T_m1
     552              :          type(auto_diff_real_star_order1) :: X, FL, scale, T_face, e_face, Peos_face, rho_face, h_face
     553              :          real(dp) :: ALFAS_ALFA, alfa, beta
     554              :          include 'formats'
     555            0 :          ierr = 0
     556            0 :          if (k > s% nz) then
     557            0 :             PII_face = 0d0
     558            0 :             return
     559              :          end if
     560            0 :          if (k == 1 .or. s% mixing_length_alpha == 0d0 .or. &
     561              :                k == s% nz) then  ! just skip k == nz to be like RSP
     562            0 :             PII_face = 0d0
     563            0 :             s% PII(k) = 0d0
     564            0 :             s% PII_ad(k) = 0d0
     565            0 :             return
     566              :          end if
     567            0 :          Y_face = s% Y_face_ad(k)  ! compute_Y_face(s, k, ierr)
     568            0 :          if (ierr /= 0) return
     569            0 :          Cp_00 = wrap_Cp_00(s, k)
     570            0 :          Cp_m1 = wrap_Cp_m1(s, k)
     571            0 :          T_00= wrap_T_00(s, k)
     572            0 :          T_m1 = wrap_T_m1(s, k)
     573            0 :          call get_RSP2_alfa_beta_face_weights(s, k, alfa, beta)
     574            0 :          Cp_face = alfa*Cp_00 + beta*Cp_m1  ! ergs g^-1 K^-1
     575            0 :          T_face = alfa*Cp_00 + beta*Cp_m1
     576            0 :          rho_face = alfa*wrap_d_00(s,k) + beta*wrap_d_m1(s,k)
     577            0 :          Peos_face = alfa*wrap_Peos_00(s,k) + beta*wrap_Peos_m1(s,k)
     578            0 :          e_face = alfa*wrap_e_00(s,k) + beta*wrap_e_m1(s,k)
     579            0 :          h_face = e_face + Peos_face/rho_face
     580            0 :          ALFAS_ALFA = x_ALFAS*s% mixing_length_alpha
     581            0 :          PII_face = ALFAS_ALFA*Cp_face*Y_face
     582              : 
     583            0 :          scale = 1d0
     584            0 :          if (Y_face > 0d0 .and. s% use_TDC_enthalpy_flux_limiter) then
     585              :             ! X = G/F
     586            0 :             X = (Cp_face*T_face/h_face)*ALFAS_ALFA* Y_face / sqrt_2_div_3
     587            0 :             FL = flux_limiter_function(X)
     588              :             ! Avoid 0/0 or tiny/tiny; for X ≈ 0, FL ≈ X so scale ~ 1 anyway.
     589            0 :             if (abs(X%val) >= 0.95d0) then
     590            0 :                scale = FL / X
     591              :             else
     592            0 :                scale = 1d0
     593              :             end if
     594              :          end if
     595              : 
     596            0 :          s% PII(k) = PII_face%val*scale%val
     597            0 :          s% PII_ad(k) = PII_face*scale
     598            0 :          if (k == -2 .and. s% PII(k) < 0d0) then
     599            0 :             write(*,2) 's% PII(k)', k, s% PII(k)
     600            0 :             write(*,2) 'Cp_face', k, Cp_face%val
     601            0 :             write(*,2) 'Y_face', k, Y_face%val
     602              :             !write(*,2) 'PII_face%val', k, PII_face%val
     603              :             !write(*,2) 'T_rho_face%val', k, T_rho_face%val
     604              :             !write(*,2) '', k,
     605              :             !write(*,2) '', k,
     606            0 :             call mesa_error(__FILE__,__LINE__,'compute_PII_face')
     607              :          end if
     608            0 :       end function compute_PII_face
     609              : 
     610            0 :       type(auto_diff_real_star_order1) function flux_limiter_function(X) result(FL) ! should be c2 continuous
     611              :         type(auto_diff_real_star_order1), intent(in) :: X
     612              :         real(dp), parameter :: X0    = 0.95_dp         ! start of transition
     613              :         real(dp), parameter :: delta = 0.05_dp         ! width of transition
     614              :         real(dp), parameter :: X1    = 1d0 !X0 + delta      ! end of transition
     615              : 
     616              :         type(auto_diff_real_star_order1) :: s, p
     617              : 
     618              :         ! Region 1: purely linear, FL = X
     619            0 :         if (X%val < X0) then ! should not be encountered
     620            0 :            FL = X
     621              : 
     622              :         ! Region 3: saturated, FL = 1
     623            0 :         else if (X%val >= X1) then
     624            0 :            FL = 1.0_dp
     625              : 
     626              :         ! Region 2: smooth C² transition between the two
     627              :         else
     628              :            ! Normalized coordinate in [0,1]
     629            0 :            s = (X - X0) / (X1 - X0)
     630              : 
     631              :            ! Quintic "smootherstep" polynomial:
     632              :            ! p(s) = 10 s^3 - 15 s^4 + 6 s^5
     633              :            ! p(0)=0, p(1)=1, p'(0)=p'(1)=0, p''(0)=p''(1)=0
     634            0 :            p = pow3(s) * (10.0_dp + s * (-15.0_dp + 6.0_dp * s))
     635              : 
     636              :            ! Blend between line FL=X and flat FL=1
     637              :            ! At s=0:  FL = X
     638              :            ! At s=1:  FL = 1
     639              :            ! Because p', p'' vanish at 0 and 1, FL, FL', FL'' all match.
     640            0 :            FL = X + (1.0_dp - X) * p
     641              :         end if
     642            0 :       end function flux_limiter_function
     643              : 
     644            0 :       function compute_d_v_div_r(s, k, ierr) result(d_v_div_r)  ! s^-1
     645              :          type (star_info), pointer :: s
     646              :          integer, intent(in) :: k
     647              :          type(auto_diff_real_star_order1) :: d_v_div_r
     648              :          integer, intent(out) :: ierr
     649              :          type(auto_diff_real_star_order1) :: v_00, v_p1, r_00, r_p1
     650              :          include 'formats'
     651            0 :          ierr = 0
     652            0 :          v_00 = wrap_v_00(s,k)
     653            0 :          v_p1 = wrap_v_p1(s,k)
     654            0 :          r_00 = wrap_r_00(s,k)
     655            0 :          r_p1 = wrap_r_p1(s,k)
     656            0 :          if (r_p1%val == 0d0) r_p1 = 1d0
     657            0 :          d_v_div_r = v_00/r_00 - v_p1/r_p1  ! units s^-1
     658            0 :       end function compute_d_v_div_r
     659              : 
     660              : 
     661            0 :       function compute_d_v_div_r_opt_time_center(s, k, ierr) result(d_v_div_r)  ! s^-1
     662              :          type (star_info), pointer :: s
     663              :          integer, intent(in) :: k
     664              :          type(auto_diff_real_star_order1) :: d_v_div_r
     665              :          integer, intent(out) :: ierr
     666              :          type(auto_diff_real_star_order1) :: v_00, v_p1, r_00, r_p1
     667              :          include 'formats'
     668            0 :          ierr = 0
     669            0 :          v_00 = wrap_opt_time_center_v_00(s,k)
     670            0 :          v_p1 = wrap_opt_time_center_v_p1(s,k)
     671            0 :          r_00 = wrap_opt_time_center_r_00(s,k)
     672            0 :          r_p1 = wrap_opt_time_center_r_p1(s,k)
     673            0 :          if (r_p1%val == 0d0) r_p1 = 1d0
     674            0 :          d_v_div_r = v_00/r_00 - v_p1/r_p1  ! units s^-1
     675            0 :       end function compute_d_v_div_r_opt_time_center
     676              : 
     677              : 
     678            0 :       function wrap_Hp_cell(s, k) result(Hp_cell)  ! cm
     679              :          type (star_info), pointer :: s
     680              :          integer, intent(in) :: k
     681              :          type(auto_diff_real_star_order1) :: Hp_cell
     682            0 :          Hp_cell = 0.5d0*(wrap_Hp_00(s,k) + wrap_Hp_p1(s,k))
     683            0 :       end function wrap_Hp_cell
     684              : 
     685              : 
     686            0 :       function Hp_cell_for_Chi(s, k, ierr) result(Hp_cell)  ! cm
     687              :          type (star_info), pointer :: s
     688              :          integer, intent(in) :: k
     689              :          integer, intent(out) :: ierr
     690              :          type(auto_diff_real_star_order1) :: Hp_cell
     691              :          type(auto_diff_real_star_order1) :: d_00, Peos_00, rmid
     692              :          real(dp) :: mmid, cgrav_mid
     693              :          include 'formats'
     694            0 :          ierr = 0
     695              : 
     696            0 :          Hp_cell = wrap_Hp_cell(s, k)
     697            0 :          return
     698              : 
     699              :          d_00 = wrap_d_00(s, k)
     700              :          Peos_00 = wrap_Peos_00(s, k)
     701              :          if (k < s% nz) then
     702              :             rmid = 0.5d0*(wrap_r_00(s,k) + wrap_r_p1(s,k))
     703              :             mmid = 0.5d0*(s% m(k) + s% m(k+1))
     704              :             cgrav_mid = 0.5d0*(s% cgrav(k) + s% cgrav(k+1))
     705              :          else
     706              :             rmid = 0.5d0*(wrap_r_00(s,k) + s% r_center)
     707              :             mmid = 0.5d0*(s% m(k) + s% m_center)
     708              :             cgrav_mid = s% cgrav(k)
     709              :          end if
     710              :          Hp_cell = pow2(rmid)*Peos_00/(d_00*cgrav_mid*mmid)
     711              :          if (s% alt_scale_height_flag) then
     712              :             call mesa_error(__FILE__,__LINE__,'Hp_cell_for_Chi: cannot use alt_scale_height_flag')
     713              :          end if
     714              :       end function Hp_cell_for_Chi
     715              : 
     716              : 
     717            0 :       function compute_Chi_cell(s, k, ierr) result(Chi_cell)
     718              :          ! eddy viscosity energy (Kuhfuss 1986) [erg]
     719              :          type (star_info), pointer :: s
     720              :          integer, intent(in) :: k
     721              :          type(auto_diff_real_star_order1) :: Chi_cell
     722              :          integer, intent(out) :: ierr
     723              :          type(auto_diff_real_star_order1) :: &
     724              :             rho2, r6_cell, d_v_div_r, Hp_cell, w_00, d_00, r_00, r_p1
     725              :          real(dp) :: f, ALFAM_ALFA
     726              :          include 'formats'
     727            0 :          ierr = 0
     728            0 :          ALFAM_ALFA = s% RSP2_alfam*s% mixing_length_alpha
     729              :          if (ALFAM_ALFA == 0d0 .or. &
     730            0 :                k <= s% RSP2_num_outermost_cells_forced_nonturbulent .or. &
     731              :                k > s% nz - int(s% nz/s% RSP2_nz_div_IBOTOM)) then
     732            0 :             Chi_cell = 0d0
     733            0 :             if (k >= 1 .and. k <= s% nz) then
     734            0 :                s% Chi(k) = 0d0
     735            0 :                s% Chi_ad(k) = 0d0
     736              :             end if
     737              :          else
     738            0 :             Hp_cell = Hp_cell_for_Chi(s, k, ierr)
     739            0 :             if (ierr /= 0) return
     740            0 :             d_v_div_r = compute_d_v_div_r(s, k, ierr)
     741            0 :             if (ierr /= 0) return
     742            0 :             w_00 = wrap_w_00(s,k)
     743            0 :             d_00 = wrap_d_00(s,k)
     744            0 :             f = (16d0/3d0)*pi*ALFAM_ALFA/s% dm(k)
     745            0 :             rho2 = pow2(d_00)
     746            0 :             r_00 = wrap_r_00(s,k)
     747            0 :             r_p1 = wrap_r_p1(s,k)
     748            0 :             r6_cell = 0.5d0*(pow6(r_00) + pow6(r_p1))
     749            0 :             Chi_cell = f*rho2*r6_cell*d_v_div_r*Hp_cell*w_00
     750              :             ! units = g^-1 cm s^-1 g^2 cm^-6 cm^6 s^-1 cm
     751              :             !       = g cm^2 s^-2
     752              :             !       = erg
     753              :          end if
     754            0 :          s% Chi(k) = Chi_cell%val
     755            0 :          s% Chi_ad(k) = Chi_cell
     756              : 
     757            0 :       end function compute_Chi_cell
     758              : 
     759              : 
     760            0 :       function compute_Eq_cell(s, k, ierr) result(Eq_cell)  ! erg g^-1 s^-1
     761              :          type (star_info), pointer :: s
     762              :          integer, intent(in) :: k
     763              :          type(auto_diff_real_star_order1) :: Eq_cell
     764              :          integer, intent(out) :: ierr
     765              :          type(auto_diff_real_star_order1) :: d_v_div_r, Chi_cell
     766              :          include 'formats'
     767            0 :          ierr = 0
     768              :          if (s% mixing_length_alpha == 0d0 .or. &
     769            0 :              k <= s% RSP2_num_outermost_cells_forced_nonturbulent .or. &
     770              :              k > s% nz - int(s% nz/s% RSP2_nz_div_IBOTOM)) then
     771            0 :             Eq_cell = 0d0
     772            0 :             if (k >= 1 .and. k <= s% nz) s% Eq_ad(k) = 0d0
     773              :          else
     774            0 :             Chi_cell = s% Chi_ad(k)  ! compute_Chi_cell(s,k,ierr)
     775            0 :             if (ierr /= 0) return
     776            0 :             d_v_div_r = compute_d_v_div_r_opt_time_center(s, k, ierr)
     777            0 :             if (ierr /= 0) return
     778            0 :             Eq_cell = 4d0*pi*Chi_cell*d_v_div_r/s% dm(k)  ! erg s^-1 g^-1
     779              :          end if
     780            0 :          s% Eq(k) = Eq_cell%val
     781            0 :          s% Eq_ad(k) = Eq_cell
     782            0 :       end function compute_Eq_cell
     783              : 
     784              : 
     785            0 :       function compute_Uq_face(s, k, ierr) result(Uq_face)  ! cm s^-2, acceleration
     786              :          type (star_info), pointer :: s
     787              :          integer, intent(in) :: k
     788              :          type(auto_diff_real_star_order1) :: Uq_face
     789              :          integer, intent(out) :: ierr
     790              :          type(auto_diff_real_star_order1) :: Chi_00, Chi_m1, r_00
     791              :          include 'formats'
     792            0 :          ierr = 0
     793              :          if (s% mixing_length_alpha == 0d0 .or. &
     794            0 :              k <= s% RSP2_num_outermost_cells_forced_nonturbulent .or. &
     795              :              k > s% nz - int(s% nz/s% RSP2_nz_div_IBOTOM)) then
     796            0 :             Uq_face = 0d0
     797              :          else
     798            0 :             r_00 = wrap_opt_time_center_r_00(s,k)
     799            0 :             Chi_00 = s% Chi_ad(k)  ! compute_Chi_cell(s,k,ierr)
     800            0 :             if (k > 1) then
     801              :                !Chi_m1 = shift_m1(compute_Chi_cell(s,k-1,ierr))
     802            0 :                Chi_m1 = shift_m1(s% Chi_ad(k-1))
     803            0 :                if (ierr /= 0) return
     804              :             else
     805            0 :                Chi_m1 = 0d0
     806              :             end if
     807            0 :             Uq_face = 4d0*pi*(Chi_m1 - Chi_00)/(r_00*s% dm_bar(k))
     808              : 
     809            0 :             if (k==-56) then
     810            0 :                write(*,3) 'RSP2 Uq chi_m1 chi_00 r', k, s% solver_iter, &
     811            0 :                   Uq_face%val, Chi_m1%val, Chi_00%val, r_00%val
     812              :             end if
     813              : 
     814              :          end if
     815              :          ! erg g^-1 cm^-1 = g cm^2 s^-2 g^-1 cm^-1 = cm s^-2, acceleration
     816            0 :          s% Uq(k) = Uq_face%val
     817            0 :       end function compute_Uq_face
     818              : 
     819              : 
     820            0 :       function compute_Source(s, k, ierr) result(Source)  ! erg g^-1 s^-1
     821              :          type (star_info), pointer :: s
     822              :          integer, intent(in) :: k
     823              :          type(auto_diff_real_star_order1) :: Source
     824              :          ! source_div_w assumes RSP2_source_seed == 0
     825              :          integer, intent(out) :: ierr
     826              :          type(auto_diff_real_star_order1) :: &
     827              :             w_00, T_00, d_00, Peos_00, Cp_00, chiT_00, chiRho_00, QQ_00, &
     828              :             Hp_face_00, Hp_face_p1, PII_face_00, PII_face_p1, PII_div_Hp_cell, &
     829              :             P_QQ_div_Cp
     830              :          include 'formats'
     831            0 :          ierr = 0
     832            0 :          w_00 = wrap_w_00(s, k)
     833            0 :          T_00 = wrap_T_00(s, k)
     834            0 :          d_00 = wrap_d_00(s, k)
     835            0 :          Peos_00 = wrap_Peos_00(s, k)
     836            0 :          Cp_00 = wrap_Cp_00(s, k)
     837            0 :          chiT_00 = wrap_chiT_00(s, k)
     838            0 :          chiRho_00 = wrap_chiRho_00(s, k)
     839            0 :          QQ_00 = chiT_00/(d_00*T_00*chiRho_00)
     840              : 
     841            0 :          Hp_face_00 = wrap_Hp_00(s,k)
     842            0 :          PII_face_00 = s% PII_ad(k)  ! compute_PII_face(s, k, ierr)
     843            0 :          if (ierr /= 0) return
     844              : 
     845            0 :          if (k == s% nz) then
     846            0 :             PII_div_Hp_cell = PII_face_00/Hp_face_00
     847              :          else
     848            0 :             Hp_face_p1 = wrap_Hp_p1(s,k)
     849            0 :             if (ierr /= 0) return
     850              :             !PII_face_p1 = shift_p1(compute_PII_face(s, k+1, ierr))
     851            0 :             PII_face_p1 = shift_p1(s% PII_ad(k+1))
     852            0 :             if (ierr /= 0) return
     853            0 :             PII_div_Hp_cell = 0.5d0*(PII_face_00/Hp_face_00 + PII_face_p1/Hp_face_p1)
     854              :          end if
     855              : 
     856              :          ! Peos_00*QQ_00/Cp_00 = grad_ad if all perfect.
     857              :          !grad_ad_00 = wrap_grad_ad_00(s, k)
     858            0 :          P_QQ_div_Cp = Peos_00*QQ_00/Cp_00  ! use this to be same as RSP
     859            0 :          Source = (w_00 + s% RSP2_source_seed)*PII_div_Hp_cell*T_00*P_QQ_div_Cp
     860              : 
     861              :          ! PII units same as Cp = erg g^-1 K^-1
     862              :          ! P*QQ/Cp is unitless (see Y_face)
     863              :          ! Source units = (erg g^-1 K^-1) cm^-1 cm s^-1 K
     864              :          !     = erg g^-1 s^-1
     865              : 
     866            0 :          if (k==-109) then
     867            0 :             write(*,3) 'RSP2 Source w PII_div_Hp T_P_QQ_div_Cp', k, s% solver_iter, &
     868            0 :                Source%val, w_00%val, PII_div_Hp_cell%val, T_00%val*P_QQ_div_Cp% val
     869              :             !write(*,3) 'RSP2 PII_00 PII_p1 Hp_00 Hp_p1', k, s% solver_iter, &
     870              :             !   PII_face_00%val, PII_face_p1%val, Hp_face_00%val, Hp_face_p1%val
     871              :          end if
     872            0 :          s% SOURCE(k) = Source%val
     873              : 
     874            0 :       end function compute_Source
     875              : 
     876              : 
     877            0 :       function compute_D(s, k, ierr) result(D)  ! erg g^-1 s^-1
     878              :          type (star_info), pointer :: s
     879              :          integer, intent(in) :: k
     880              :          type(auto_diff_real_star_order1) :: D
     881              :          type(auto_diff_real_star_order1) :: dw3, w_00
     882              :          integer, intent(out) :: ierr
     883              :          type(auto_diff_real_star_order1) :: Hp_cell
     884              :          include 'formats'
     885            0 :          ierr = 0
     886            0 :          if (s% mixing_length_alpha == 0d0) then
     887            0 :             D = 0d0
     888              :          else
     889            0 :             Hp_cell = wrap_Hp_cell(s,k)
     890            0 :             w_00 = wrap_w_00(s,k)
     891            0 :             dw3 = pow3(w_00) - pow3(s% RSP2_w_min_for_damping)
     892            0 :             D = (s% RSP2_alfad*x_CEDE/s% mixing_length_alpha)*dw3/Hp_cell
     893              :             ! units cm^3 s^-3 cm^-1 = cm^2 s^-3 = erg g^-1 s^-1
     894              :          end if
     895            0 :          if (k==-50) then
     896            0 :             write(*,3) 'RSP2 DAMP w Hp_cell dw3', k, s% solver_iter, &
     897            0 :                D%val, w_00%val, Hp_cell%val, dw3% val
     898              :          end if
     899            0 :          s% DAMP(k) = D%val
     900            0 :       end function compute_D
     901              : 
     902              : 
     903            0 :       function compute_Dr(s, k, ierr) result(Dr)  ! erg g^-1 s^-1 = cm^2 s^-3
     904              :          type (star_info), pointer :: s
     905              :          integer, intent(in) :: k
     906              :          type(auto_diff_real_star_order1) :: Dr
     907              :          integer, intent(out) :: ierr
     908              :          type(auto_diff_real_star_order1) :: &
     909              :             w_00, T_00, d_00, Cp_00, kap_00, Hp_cell, POM2
     910              :          real(dp) :: gammar, alpha, POM
     911              :          include 'formats'
     912            0 :          ierr = 0
     913            0 :          alpha = s% mixing_length_alpha
     914            0 :          gammar = s% RSP2_alfar*x_GAMMAR
     915            0 :          if (gammar == 0d0) then
     916            0 :             Dr = 0d0
     917            0 :             s% DAMPR(k) = 0d0
     918            0 :             return
     919              :          end if
     920            0 :          w_00 = wrap_w_00(s,k)
     921            0 :          T_00 = wrap_T_00(s,k)
     922            0 :          d_00 = wrap_d_00(s,k)
     923            0 :          Cp_00 = wrap_Cp_00(s,k)
     924            0 :          kap_00 = wrap_kap_00(s,k)
     925            0 :          Hp_cell = wrap_Hp_cell(s,k)
     926            0 :          POM = 4d0*boltz_sigma*pow2(gammar/alpha)  ! erg cm^-2 K^-4 s^-1
     927            0 :          POM2 = pow3(T_00)/(pow2(d_00)*Cp_00*kap_00)
     928              :             ! K^3 / ((g cm^-3)^2 (erg g^-1 K^-1) (cm^2 g^-1))
     929              :             ! K^3 / (cm^-4 erg K^-1) = K^4 cm^4 erg^-1
     930            0 :          Dr = get_etrb(s,k)*POM*POM2/pow2(Hp_cell)
     931              :          ! (erg cm^-2 K^-4 s^-1) (K^4 cm^4 erg^-1) cm^2 s^-2 cm^-2
     932              :          ! cm^2 s^-3 = erg g^-1 s^-1
     933            0 :          s% DAMPR(k) = Dr%val
     934            0 :       end function compute_Dr
     935              : 
     936              : 
     937            0 :       function compute_C(s, k, ierr) result(C)  ! erg g^-1 s^-1
     938              :          type (star_info), pointer :: s
     939              :          integer, intent(in) :: k
     940              :          type(auto_diff_real_star_order1) :: C
     941              :          integer, intent(out) :: ierr
     942              :          type(auto_diff_real_star_order1) :: Source, D, Dr
     943              :          if (s% mixing_length_alpha == 0d0 .or. &
     944            0 :              k <= s% RSP2_num_outermost_cells_forced_nonturbulent .or. &
     945              :              k > s% nz - int(s% nz/s% RSP2_nz_div_IBOTOM)) then
     946            0 :             if (k >= 1 .and. k <= s% nz) then
     947            0 :                s% SOURCE(k) = 0d0
     948            0 :                s% DAMP(k) = 0d0
     949            0 :                s% DAMPR(k) = 0d0
     950            0 :                s% COUPL(k) = 0d0
     951            0 :                s% COUPL_ad(k) = 0d0
     952              :             end if
     953            0 :             C = 0d0
     954            0 :             return
     955              :          end if
     956            0 :          Source = compute_Source(s, k, ierr)
     957            0 :          if (ierr /= 0) return
     958            0 :          D = compute_D(s, k, ierr)
     959            0 :          if (ierr /= 0) return
     960            0 :          Dr = compute_Dr(s, k, ierr)
     961            0 :          if (ierr /= 0) return
     962            0 :          C = Source - D - Dr
     963            0 :          s% COUPL(k) = C%val
     964            0 :          s% COUPL_ad(k) = C
     965            0 :       end function compute_C
     966              : 
     967              : 
     968            0 :       function compute_L_face(s, k, ierr) result(L_face)  ! erg s^-1
     969              :          type (star_info), pointer :: s
     970              :          integer, intent(in) :: k
     971              :          type(auto_diff_real_star_order1) :: L_face
     972              :          integer, intent(out) :: ierr
     973              :          type(auto_diff_real_star_order1) :: Lr, Lc, Lt
     974            0 :          call compute_L_terms(s, k, L_face, Lr, Lc, Lt, ierr)
     975            0 :       end function compute_L_face
     976              : 
     977              : 
     978            0 :       subroutine compute_L_terms(s, k, L, Lr, Lc, Lt, ierr)
     979              :          type (star_info), pointer, intent(in) :: s
     980              :          integer, intent(in) :: k
     981              :          type(auto_diff_real_star_order1), intent(out) :: L, Lr, Lc, Lt
     982              :          type(accurate_auto_diff_real_star_order1) :: L_sum
     983              :          integer, intent(out) :: ierr
     984              :          include 'formats'
     985            0 :          ierr = 0
     986            0 :          if (k > s% nz) then
     987            0 :             L = 0d0
     988            0 :             L%val = s% L_center
     989            0 :             Lr = 0d0
     990            0 :             Lc = 0d0
     991            0 :             Lt = 0d0
     992            0 :             return
     993              :          end if
     994            0 :          Lr = compute_Lr(s, k, ierr)
     995            0 :          if (ierr /= 0) return
     996            0 :          if (k == 1) then
     997            0 :             Lc = 0d0
     998            0 :             Lt = 0d0
     999              :          else
    1000            0 :             Lc = compute_Lc(s, k, ierr)
    1001            0 :             if (ierr /= 0) return
    1002            0 :             Lt = compute_Lt(s, k, ierr)
    1003            0 :             if (ierr /= 0) return
    1004              :          end if
    1005            0 :          L_sum = Lr
    1006            0 :          L_sum = L_sum + Lc
    1007            0 :          L_sum = L_sum + Lt
    1008            0 :          L = L_sum
    1009            0 :          s% Lr_ad(k) = Lr
    1010            0 :          s% Lc_ad(k) = Lc
    1011            0 :          s% Lt_ad(k) = Lt
    1012              :       end subroutine compute_L_terms
    1013              : 
    1014              : 
    1015            0 :       function compute_Lr(s, k, ierr) result(Lr)  ! erg s^-1
    1016              :          type (star_info), pointer :: s
    1017              :          integer, intent(in) :: k
    1018              :          type(auto_diff_real_star_order1) :: Lr
    1019              :          integer, intent(out) :: ierr
    1020              :          type(auto_diff_real_star_order1) :: &
    1021              :             r_00, area, T_00, T400, Erad, T_m1, T4m1, &
    1022              :             kap_00, kap_m1, kap_face, diff_T4_div_kap, BW, BK
    1023              :          real(dp) :: alfa
    1024              :          include 'formats'
    1025            0 :          ierr = 0
    1026            0 :          if (k > s% nz) then
    1027            0 :             Lr = s% L_center
    1028              :          else
    1029            0 :             r_00 = wrap_r_00(s,k)  ! not time centered
    1030            0 :             area = 4d0*pi*pow2(r_00)
    1031            0 :             T_00 = wrap_T_00(s,k)
    1032            0 :             T400 = pow4(T_00)
    1033            0 :             if (k == 1) then  ! Lr(1) proportional to Erad in cell(1)
    1034            0 :                Erad = crad * T400
    1035            0 :                Lr = s% RSP2_Lsurf_factor * area * clight * Erad
    1036            0 :                s% Lr(k) = Lr%val
    1037            0 :                return
    1038              :             end if
    1039            0 :             T_m1 = wrap_T_m1(s,k)
    1040            0 :             T4m1 = pow4(T_m1)
    1041            0 :             alfa = s% dq(k-1)/(s% dq(k-1) + s% dq(k))
    1042            0 :             kap_00 = wrap_kap_00(s,k)
    1043            0 :             kap_m1 = wrap_kap_m1(s,k)
    1044            0 :             kap_face = alfa*kap_00 + (1d0 - alfa)*kap_m1
    1045            0 :             diff_T4_div_kap = (T4m1 - T400)/kap_face
    1046              : 
    1047            0 :             if (s% RSP2_use_Stellingwerf_Lr) then  ! RSP style
    1048            0 :                BW = log(T4m1/T400)
    1049            0 :                if (abs(BW%val) > 1d-20) then
    1050            0 :                   BK = log(kap_m1/kap_00)
    1051            0 :                   if (abs(1d0 - BK%val/BW%val) > 1d-15 .and. abs(BW%val - BK%val) > 1d-15) then
    1052            0 :                      diff_T4_div_kap = (T4m1/kap_m1 - T400/kap_00)/(1d0 - BK/BW)
    1053              :                   end if
    1054              :                end if
    1055              :             end if
    1056            0 :             Lr = -crad*clight/3d0*diff_T4_div_kap*pow2(area)/s% dm_bar(k)
    1057              :             ! units (erg cm^-3 K^-4) (cm s^-1) (K^4 cm^-2 g cm^4) g^-1 = erg s^-1
    1058              : 
    1059              :             !s% xtra1_array(k) = s% T_start(k)
    1060              :             !s% xtra2_array(k) = T4m1%val - T400%val
    1061              :             !s% xtra3_array(k) = kap_face%val
    1062              :             !s% xtra4_array(k) = diff_T4_div_kap%val
    1063              :             !s% xtra5_array(k) = Lr%val/Lsun
    1064              :             !s% xtra6_array(k) = 1
    1065              : 
    1066              :          end if
    1067            0 :          s% Lr(k) = Lr%val
    1068            0 :       end function compute_Lr
    1069              : 
    1070              : 
    1071            0 :       function compute_Lc(s, k, ierr) result(Lc)  ! erg s^-1
    1072              :          type (star_info), pointer :: s
    1073              :          integer, intent(in) :: k
    1074              :          type(auto_diff_real_star_order1) :: Lc
    1075              :          integer, intent(out) :: ierr
    1076              :          type(auto_diff_real_star_order1) :: Lc_div_w_face
    1077            0 :          Lc = compute_Lc_terms(s, k, Lc_div_w_face, ierr)
    1078            0 :          s% Lc(k) = Lc%val
    1079            0 :       end function compute_Lc
    1080              : 
    1081              : 
    1082            0 :       function compute_Lc_terms(s, k, Lc_div_w_face, ierr) result(Lc)
    1083              :          type (star_info), pointer :: s
    1084              :          integer, intent(in) :: k
    1085              :          type(auto_diff_real_star_order1) :: Lc, Lc_div_w_face
    1086              :          integer, intent(out) :: ierr
    1087              :          type(auto_diff_real_star_order1) :: r_00, area, &
    1088              :             T_m1, T_00, d_m1, d_00, w_m1, w_00, T_rho_face, PII_face, w_face
    1089              :          real(dp) :: ALFAC, ALFAS, alfa, beta
    1090              :          include 'formats'
    1091            0 :          ierr = 0
    1092              :          if (s% mixing_length_alpha == 0d0 .or. &
    1093            0 :              k <= s% RSP2_num_outermost_cells_forced_nonturbulent .or. &
    1094              :              k > s% nz - int(s% nz/s% RSP2_nz_div_IBOTOM)) then
    1095            0 :             Lc = 0d0
    1096            0 :             Lc_div_w_face = 1
    1097            0 :             return
    1098              :          end if
    1099            0 :          r_00 = wrap_r_00(s, k)
    1100            0 :          area = 4d0*pi*pow2(r_00)
    1101            0 :          T_m1 = wrap_T_m1(s, k)
    1102            0 :          T_00 = wrap_T_00(s, k)
    1103            0 :          d_m1 = wrap_d_m1(s, k)
    1104            0 :          d_00 = wrap_d_00(s, k)
    1105            0 :          w_m1 = wrap_w_m1(s, k)
    1106            0 :          w_00 = wrap_w_00(s, k)
    1107            0 :          call get_RSP2_alfa_beta_face_weights(s, k, alfa, beta)
    1108            0 :          T_rho_face = alfa*T_00*d_00 + beta*T_m1*d_m1
    1109            0 :          PII_face = s% PII_ad(k)  ! compute_PII_face(s, k, ierr)
    1110            0 :          w_face = alfa*w_00 + beta*w_m1
    1111            0 :          ALFAC = x_ALFAC
    1112            0 :          ALFAS = x_ALFAS
    1113            0 :          Lc_div_w_face = area*(ALFAC/ALFAS)*T_rho_face*PII_face
    1114              :          ! units = cm^2 K g cm^-3 ergs g^-1 K^-1 = ergs cm^-1
    1115            0 :          Lc = w_face*Lc_div_w_face
    1116              :          ! units = cm s^-1 ergs cm^-1 = ergs s^-1
    1117            0 :          if (k == -458) then
    1118            0 :             write(*,2) 'Lc%val', k, Lc%val
    1119            0 :             write(*,2) 'w_face%val', k, w_face%val
    1120            0 :             write(*,2) 'Lc_div_w_face', k, Lc_div_w_face%val
    1121            0 :             write(*,2) 'PII_face%val', k, PII_face%val
    1122            0 :             write(*,2) 'T_rho_face%val', k, T_rho_face%val
    1123              :             !write(*,2) '', k,
    1124              :             !write(*,2) '', k,
    1125            0 :             call mesa_error(__FILE__,__LINE__,'compute_Lc_terms')
    1126              :          end if
    1127            0 :       end function compute_Lc_terms
    1128              : 
    1129              : 
    1130            0 :       function compute_Lt(s, k, ierr) result(Lt)  ! erg s^-1
    1131              :          type (star_info), pointer :: s
    1132              :          integer, intent(in) :: k
    1133              :          type(auto_diff_real_star_order1) :: Lt
    1134              :          integer, intent(out) :: ierr
    1135              :          type(auto_diff_real_star_order1) :: r_00, area2, d_m1, d_00, &
    1136              :             rho2_face, Hp_face, w_m1, w_00, w_face, etrb_m1, etrb_00
    1137              :          real(dp) :: alpha_alpha_t, alfa, beta
    1138              :          include 'formats'
    1139            0 :          ierr = 0
    1140            0 :          if (k > s% nz) then
    1141            0 :             Lt = 0d0
    1142            0 :             return
    1143              :          end if
    1144            0 :          alpha_alpha_t = s% mixing_length_alpha*s% RSP2_alfat
    1145              :          if (alpha_alpha_t == 0d0 .or. &
    1146            0 :              k <= s% RSP2_num_outermost_cells_forced_nonturbulent .or. &
    1147              :              k > s% nz - int(s% nz/s% RSP2_nz_div_IBOTOM)) then
    1148            0 :             Lt = 0d0
    1149            0 :             s% Lt(k) = 0d0
    1150            0 :             return
    1151              :          end if
    1152            0 :          r_00 = wrap_r_00(s,k)
    1153            0 :          area2 = pow2(4d0*pi*pow2(r_00))
    1154            0 :          d_m1 = wrap_d_m1(s,k)
    1155            0 :          d_00 = wrap_d_00(s,k)
    1156            0 :          call get_RSP2_alfa_beta_face_weights(s, k, alfa, beta)
    1157            0 :          rho2_face = alfa*pow2(d_00) + beta*pow2(d_m1)
    1158            0 :          w_m1 = wrap_w_m1(s,k)
    1159            0 :          w_00 = wrap_w_00(s,k)
    1160            0 :          w_face = alfa*w_00 + beta*w_m1
    1161            0 :          etrb_m1 = wrap_etrb_m1(s,k)
    1162            0 :          etrb_00 = wrap_etrb_00(s,k)
    1163            0 :          Hp_face = wrap_Hp_00(s,k)
    1164              :          ! Ft = - alpha_t * rho_face * alpha * Hp_face * w_face * detrb/dr (thesis eqn 2.44)
    1165              :          ! replace dr by dm_bar/(area*rho_face)
    1166              :          ! Ft = - alpha_alpha_t * rho_face * Hp_face * w_face * (area*rho_face) * detrb/dm_bar
    1167              :          ! Lt = area * Ft
    1168              :          ! Lt = -alpha_alpha_t * (area*rho_face)**2 * Hp_face * w_face * (etrb(k-1) - etrb(k))/dm_bar
    1169            0 :          Lt = - alpha_alpha_t * area2 * rho2_face * Hp_face * w_face * (etrb_m1 - etrb_00) / s% dm_bar(k)
    1170              :          ! units = (cm^4) (g^2 cm^-6) (cm) (cm s^-1) (ergs g^-1) g^-1 = erg s^-1
    1171            0 :          s% Lt(k) = Lt%val
    1172            0 :       end function compute_Lt
    1173              : 
    1174              : 
    1175            0 :       subroutine set_etrb_start_vars(s, ierr)
    1176              :          type (star_info), pointer :: s
    1177              :          integer, intent(out) :: ierr
    1178              :          integer :: k
    1179              :          type(auto_diff_real_star_order1) :: Y_face, Lt
    1180              :          include 'formats'
    1181            0 :          ierr = 0
    1182            0 :          do k=1,s%nz
    1183            0 :             Y_face = compute_Y_face(s, k, ierr)
    1184            0 :             if (ierr /= 0) return
    1185            0 :             s% Y_face_start(k) = Y_face%val
    1186            0 :             Lt = compute_Lt(s, k, ierr)
    1187            0 :             if (ierr /= 0) return
    1188            0 :             s% Lt_start(k) = Lt%val
    1189            0 :             s% w_start(k) = s% w(k)
    1190            0 :             s% Hp_face_start(k) = s% Hp_face(k)
    1191              :          end do
    1192              :       end subroutine set_etrb_start_vars
    1193              : 
    1194              : 
    1195            0 :       subroutine RSP2_adjust_vars_before_call_solver(s, ierr)  ! replaces check_omega in RSP
    1196              :          ! JAK OKRESLIC OMEGA DLA PIERWSZEJ ITERACJI
    1197              :          use micro, only: do_eos_for_cell
    1198              :          type (star_info), pointer :: s
    1199              :          integer, intent(out) :: ierr
    1200              :          real(dp) :: PII_div_Hp, QQ, SOURCE, Hp_cell, DAMP, POM, POM2, DAMPR, del, soln
    1201              :          !type(auto_diff_real_star_order1) :: x
    1202              :          integer :: k
    1203              :          include 'formats'
    1204            0 :          ierr = 0
    1205            0 :          if (s% mixing_length_alpha == 0d0) return
    1206              : 
    1207            0 :          !$OMP PARALLEL DO PRIVATE(k,PII_div_Hp,QQ,SOURCE,Hp_cell,DAMP,POM,POM2,DAMPR,del,soln) SCHEDULE(dynamic,2)
    1208              :          do k=s% RSP2_num_outermost_cells_forced_nonturbulent+1, &
    1209              :                s% nz - max(1,int(s% nz/s% RSP_nz_div_IBOTOM))
    1210              : 
    1211              :             if (s% w(k) > s% RSP2_w_min_for_damping) cycle
    1212              : 
    1213              :             PII_div_Hp = 0.5d0*(s% PII(k)/s% Hp_face(k) + s% PII(k+1)/s% Hp_face(k+1))
    1214              :             QQ = s% chiT(k)/(s% rho(k)*s% T(k)*s% chiRho(k))
    1215              :             SOURCE = PII_div_Hp*s% T(k)*s% Peos(k)*QQ/s% Cp(k)
    1216              : 
    1217              :             Hp_cell = 0.5d0*(s% Hp_face(k) + s% Hp_face(k+1))
    1218              :             DAMP = (s% RSP2_alfad*x_CEDE/s% mixing_length_alpha)/Hp_cell
    1219              : 
    1220              :             POM = 4d0*boltz_sigma*pow2(s% RSP2_alfar*x_GAMMAR/s% mixing_length_alpha)
    1221              :             POM2 = pow3(s% T(k))/(pow2(s% rho(k))*s% Cp(k)*s% opacity(k))
    1222              :             DAMPR = POM*POM2/pow2(Hp_cell)
    1223              : 
    1224              :             del = pow2(DAMPR) + 4d0*DAMP*SOURCE
    1225              : 
    1226              :             if (k==-35) then
    1227              :                write(*,2) 'del', k, del
    1228              :                write(*,2) 'DAMPR', k, DAMPR
    1229              :                write(*,2) 'DAMP', k, DAMP
    1230              :                write(*,2) 'SOURCE', k, SOURCE
    1231              :                write(*,2) 'POM', k, PII_div_Hp
    1232              :                write(*,2) 'POM2', k, s% T(k)*s% Peos(k)*QQ/s% Cp(k)
    1233              :                write(*,2) 's% Hp_face(k)', k, s% Hp_face(k)
    1234              :                write(*,2) 's% Hp_face(k+1)', k+1, s% Hp_face(k+1)
    1235              :                write(*,2) 's% PII(k)', k, s% PII(k)
    1236              :                write(*,2) 's% PII(k+1)', k+1, s% PII(k+1)
    1237              :                write(*,2) 's% Y_face(k)', k, s% Y_face(k)
    1238              :                write(*,2) 's% Y_face(k+1)', k+1, s% Y_face(k+1)
    1239              :             end if
    1240              : 
    1241              :             if (del < 0d0) cycle
    1242              :             soln = (-DAMPR + sqrt(del))/(2d0*DAMP)
    1243              :             if (k==-35) write(*,2) 'soln', k, soln
    1244              :             if (soln > 0d0) then
    1245              :                ! i tried soln = sqrt(soln) here. helps solver convergence, but hurts the model results.
    1246              :                if (s% RSP2_report_adjust_w) &
    1247              :                   write(*,3) 'RSP2_adjust_vars_before_call_solver w', k, s% model_number, s% w(k), soln
    1248              :                s% w(k) = soln
    1249              :             end if
    1250              : 
    1251              :          end do
    1252              :          !$OMP END PARALLEL DO
    1253              :       end subroutine RSP2_adjust_vars_before_call_solver
    1254              : 
    1255              :       end module hydro_rsp2
        

Generated by: LCOV version 2.0-1