LCOV - code coverage report
Current view: top level - star/private - hydro_energy.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 61.2 % 428 262
Test Date: 2026-08-13 11:55:22 Functions: 93.8 % 16 15

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2018-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 hydro_energy
      21              : 
      22              :       use star_private_def
      23              :       use const_def, only: dp, ln10, pi, pi4
      24              :       use utils_lib, only: mesa_error, is_bad
      25              :       use auto_diff
      26              :       use auto_diff_support
      27              :       use star_utils, only: em1, e00, ep1, set_energy_eqn_scal
      28              : 
      29              :       implicit none
      30              : 
      31              :       private
      32              :       public :: do1_energy_eqn
      33              : 
      34              :       contains
      35              : 
      36        52348 :       subroutine do1_energy_eqn( &  ! energy conservation
      37              :             s, k, do_chem, nvar, ierr)
      38              :          use star_utils, only: store_partials
      39              :          type (star_info), pointer :: s
      40              :          integer, intent(in) :: k, nvar
      41              :          logical, intent(in) :: do_chem
      42              :          integer, intent(out) :: ierr
      43            0 :          real(dp), dimension(nvar) :: d_dm1, d_d00, d_dp1
      44              :          include 'formats'
      45              :          call get1_energy_eqn( &
      46              :             s, k, do_chem, nvar, &
      47        52348 :             d_dm1, d_d00, d_dp1, ierr)
      48        52348 :          if (ierr /= 0) then
      49            0 :             if (s% report_ierr) write(*,2) 'ierr /= 0 for get1_energy_eqn', k
      50              :             return
      51              :          end if
      52              :          call store_partials( &
      53        52348 :             s, k, s% i_dlnE_dt, nvar, d_dm1, d_d00, d_dp1, 'do1_energy_eqn', ierr)
      54        52348 :       end subroutine do1_energy_eqn
      55              : 
      56              : 
      57        52348 :       subroutine get1_energy_eqn( &
      58        52348 :             s, k, do_chem, nvar, d_dm1, d_d00, d_dp1, ierr)
      59              :          use eos_def, only: i_grad_ad, i_lnPgas, i_lnE
      60              :          use eps_grav, only: eval_eps_grav_and_partials
      61              :          use accurate_sum_auto_diff_star_order1
      62              :          use auto_diff_support
      63              :          type (star_info), pointer :: s
      64              :          integer, intent(in) :: k, nvar
      65              :          logical, intent(in) :: do_chem
      66              :          real(dp), intent(out), dimension(nvar) :: d_dm1, d_d00, d_dp1
      67              :          integer, intent(out) :: ierr
      68              : 
      69              :          type(auto_diff_real_star_order1) :: resid_ad, &
      70              :             dL_dm_ad, sources_ad, others_ad, d_turbulent_energy_dt_ad, &
      71              :             dwork_dm_ad, eps_grav_ad, dke_dt_ad, dpe_dt_ad, de_dt_ad
      72              :          type(accurate_auto_diff_real_star_order1) :: esum_ad
      73              :          real(dp) :: residual, dm, dt, scal
      74              :          real(dp), dimension(s% species) :: &
      75        52348 :             d_dwork_dxam1, d_dwork_dxa00, d_dwork_dxap1
      76              :          integer :: nz, i_dlnE_dt, i_lum, i_v
      77              :          logical :: test_partials, doing_op_split_burn, eps_grav_form
      78              : 
      79              :          include 'formats'
      80              : 
      81              :          !test_partials = (k == s% solver_test_partials_k)
      82        52348 :          test_partials = .false.
      83              : 
      84        52348 :          ierr = 0
      85        52348 :          call init
      86              : 
      87        52348 :          call setup_eps_grav(ierr); if (ierr /= 0) return  ! do this first - it sets eps_grav_form
      88        52348 :          call setup_de_dt_and_friends(ierr); if (ierr /= 0) return
      89        52348 :          call setup_dwork_dm(ierr); if (ierr /= 0) return
      90        52348 :          call setup_dL_dm(ierr); if (ierr /= 0) return
      91        52348 :          call setup_sources_and_others(ierr); if (ierr /= 0) return
      92        52348 :          call setup_d_turbulent_energy_dt(ierr); if (ierr /= 0) return
      93        52348 :          call set_energy_eqn_scal(s, k, scal, ierr); if (ierr /= 0) return
      94              : 
      95        52348 :          s% dL_dm(k) = dL_dm_ad%val
      96        52348 :          s% dwork_dm(k) = dwork_dm_ad%val
      97        52348 :          s% energy_sources(k) = sources_ad%val
      98              :             ! nuclear heating, non_nuc_neu_cooling, irradiation heating, extra_heat, eps_mdot
      99        52348 :          s% energy_others(k) = others_ad%val
     100              :             ! eps_WD_sedimentation, eps_diffusion, eps_pre_mix, eps_phase_separation
     101              :          ! sum terms in esum_ad using accurate_auto_diff_real_star_order1
     102        52348 :          if (eps_grav_form) then  ! for this case, dwork_dm doesn't include work by P since that is in eps_grav
     103            0 :             esum_ad = -dL_dm_ad
     104            0 :             esum_ad = esum_ad + sources_ad
     105            0 :             esum_ad = esum_ad + others_ad
     106            0 :             esum_ad = esum_ad - d_turbulent_energy_dt_ad
     107            0 :             esum_ad = esum_ad - dwork_dm_ad
     108            0 :             esum_ad = esum_ad + eps_grav_ad
     109        52348 :          else if (s% using_velocity_time_centering .and. &
     110              :                 s% use_P_d_1_div_rho_form_of_work_when_time_centering_velocity) then
     111            0 :             esum_ad = -dL_dm_ad
     112            0 :             esum_ad = esum_ad + sources_ad
     113            0 :             esum_ad = esum_ad + others_ad
     114            0 :             esum_ad = esum_ad - d_turbulent_energy_dt_ad
     115            0 :             esum_ad = esum_ad - dwork_dm_ad
     116            0 :             esum_ad = esum_ad - de_dt_ad
     117              :          else
     118        52348 :             esum_ad = -dL_dm_ad
     119        52348 :             esum_ad = esum_ad + sources_ad
     120        52348 :             esum_ad = esum_ad + others_ad
     121        52348 :             esum_ad = esum_ad - d_turbulent_energy_dt_ad
     122        52348 :             esum_ad = esum_ad - dwork_dm_ad
     123        52348 :             esum_ad = esum_ad - dke_dt_ad
     124        52348 :             esum_ad = esum_ad - dpe_dt_ad
     125        52348 :             esum_ad = esum_ad - de_dt_ad
     126              :          end if
     127        52348 :          resid_ad = esum_ad  ! convert back to auto_diff_real_star_order1
     128        52348 :          s% ergs_error(k) = -dm*dt*resid_ad%val  ! save ergs_error before scaling
     129        52348 :          resid_ad = scal*resid_ad
     130        52348 :          residual = resid_ad%val
     131        52348 :          s% equ(i_dlnE_dt, k) = residual
     132              : 
     133              :          if (test_partials) then
     134              :             s% solver_test_partials_val = residual
     135              :          end if
     136        52348 :          call unpack_res18(s% species, resid_ad)
     137              : 
     138              :          if (test_partials) then
     139              :             s% solver_test_partials_var = s% i_u
     140              :             s% solver_test_partials_dval_dx = d_d00(s% solver_test_partials_var)
     141              :             write(*,*) 'get1_energy_eqn', s% solver_test_partials_var
     142              :             if (eps_grav_form) write(*,*) 'eps_grav_form', eps_grav_form
     143              :             !if (.false. .and. s% solver_iter == s% solver_test_partials_iter_number) then
     144              :             if (.true.) then
     145              :                write(*,2) 'scal', k, scal
     146              :                write(*,2) 'residual', k, residual
     147              :                write(*,2) 'sources*scal', k, sources_ad%val*scal
     148              :                write(*,2) '-dL_dm*scal', k, -dL_dm_ad%val*scal
     149              :                write(*,2) '-d_turbulent_energy_dt*scal', k, -d_turbulent_energy_dt_ad%val*scal
     150              :                write(*,2) '-dwork_dm*scal', k, -dwork_dm_ad%val*scal
     151              :                write(*,2) '-dke_dt*scal', k, -dke_dt_ad%val*scal
     152              :                write(*,2) '-dpe_dt*scal', k, -dpe_dt_ad%val*scal
     153              :                write(*,2) 'gradT', k, s% gradT(k)
     154              :                write(*,2) 'opacity', k, s% opacity(k)
     155              :                write(*,2) 'logT', k, s% lnT(k)/ln10
     156              :                write(*,2) 'logRho', k, s% lnd(k)/ln10
     157              :                write(*,2) 'X', k, s% X(k)
     158              :                write(*,2) 'Z', k, s% Z(k)
     159              :             end if
     160              :             write(*,'(A)')
     161              :          end if
     162              : 
     163              :          contains
     164              : 
     165        52348 :          subroutine init
     166        52348 :             i_dlnE_dt = s% i_dlnE_dt
     167        52348 :             i_lum = s% i_lum
     168        52348 :             i_v = s% i_v
     169        52348 :             nz = s% nz
     170        52348 :             dt = s% dt
     171        52348 :             dm = s% dm(k)
     172              :             doing_op_split_burn = s% op_split_burn .and. &
     173        52348 :                s% T_start(k) >= s% op_split_burn_min_T
     174      1936876 :             d_dm1 = 0d0; d_d00 = 0d0; d_dp1 = 0d0
     175        52348 :          end subroutine init
     176              : 
     177        52348 :          subroutine setup_dwork_dm(ierr)
     178              :             integer, intent(out) :: ierr
     179              :             real(dp) :: dwork
     180              :             logical :: skip_P
     181              :             include 'formats'
     182              :             ierr = 0
     183        52348 :             skip_P = eps_grav_form
     184        52348 :             if (s% using_velocity_time_centering .and. &
     185              :                 s% use_P_d_1_div_rho_form_of_work_when_time_centering_velocity) then
     186              :                call eval_simple_PdV_work(s, k, skip_P, dwork_dm_ad, dwork, &
     187            0 :                   d_dwork_dxa00, ierr)
     188            0 :                d_dwork_dxam1 = 0
     189            0 :                d_dwork_dxap1 = 0
     190            0 :                if (k == s% nz) then
     191            0 :                   s% work_inward_at_center = pi4*pow2(s% r_center)*s% Peos_start(s% nz)*s% v_center
     192            0 :                   if (is_bad(s% work_inward_at_center)) then
     193            0 :                      write(*,2) 'work_inward_at_center', s% model_number, s% work_inward_at_center
     194            0 :                      write(*,2) 'Peos_start', s% model_number, s% Peos_start(s% nz)
     195            0 :                      write(*,2) 'v_center', s% model_number, s% v_center
     196            0 :                      write(*,2) 'r_center', s% model_number, s% r_center
     197            0 :                      call mesa_error(__FILE__,__LINE__,'setup_dwork_dm')
     198              :                   end if
     199              :                end if
     200              :             else
     201              :                call eval_dwork(s, k, skip_P, dwork_dm_ad, dwork, &
     202        52348 :                   d_dwork_dxam1, d_dwork_dxa00, d_dwork_dxap1, ierr)
     203              :             end if
     204        52348 :             if (ierr /= 0) then
     205            0 :                if (s% report_ierr) write(*,*) 'failed in setup_dwork_dm', k
     206            0 :                return
     207              :             end if
     208        52348 :             dwork_dm_ad = dwork_dm_ad/dm
     209              :          end subroutine setup_dwork_dm
     210              : 
     211        52348 :          subroutine setup_dL_dm(ierr)
     212              :             integer, intent(out) :: ierr
     213              :             type(auto_diff_real_star_order1) :: L00_ad, Lp1_ad
     214              :             real(dp) :: L_theta
     215              :             include 'formats'
     216        52348 :             ierr = 0
     217              :             if (s% using_velocity_time_centering .and. &
     218              :                      s% include_L_in_velocity_time_centering &
     219        52348 :                      .and. s% lnT(k)/ln10 <= s% max_logT_for_include_P_and_L_in_velocity_time_centering) then
     220            0 :                L_theta = s% L_theta_for_velocity_time_centering
     221              :             else
     222        52348 :                L_theta = 1d0
     223              :             end if
     224        52348 :             L00_ad = L_theta*wrap_L_00(s, k) + (1d0 - L_theta)*s% L_start(k)
     225        52348 :             Lp1_ad = wrap_L_p1(s, k)
     226        52348 :             if (k < s% nz) Lp1_ad = L_theta*Lp1_ad + (1d0 - L_theta)*s% L_start(k+1)
     227        52348 :             dL_dm_ad = (L00_ad - Lp1_ad)/dm
     228        52348 :          end subroutine setup_dL_dm
     229              : 
     230              : 
     231        52348 :          subroutine setup_sources_and_others(ierr) ! sources_ad, others_ad
     232              :             use hydro_rsp2, only: compute_Eq_cell
     233              :             use tdc_hydro, only: compute_tdc_Eq_div_w_face
     234              :             real(dp) :: alfa, beta
     235              :             integer, intent(out) :: ierr
     236              :             type(auto_diff_real_star_order1) :: &
     237              :                eps_nuc_ad, non_nuc_neu_ad, extra_heat_ad, Eq_ad, RTI_diffusion_ad, &
     238              :                v_00, v_p1, drag_force, drag_energy
     239              :             type(accurate_auto_diff_real_star_order1) :: sources_sum_ad
     240              :             include 'formats'
     241        52348 :             ierr = 0
     242              : 
     243        52348 :             if (s% eps_nuc_factor == 0d0 .or. s% nonlocal_NiCo_decay_heat) then
     244            0 :                eps_nuc_ad = 0  ! get eps_nuc from extra_heat instead
     245        52348 :             else if (s% op_split_burn .and. s% T_start(k) >= s% op_split_burn_min_T) then
     246            0 :                eps_nuc_ad = 0d0
     247            0 :                eps_nuc_ad%val = s% burn_avg_epsnuc(k)
     248              :             else
     249        52348 :                eps_nuc_ad = 0d0
     250        52348 :                eps_nuc_ad%val = s% eps_nuc(k)
     251        52348 :                eps_nuc_ad%d1Array(i_lnd_00) = s% d_epsnuc_dlnd(k)
     252        52348 :                eps_nuc_ad%d1Array(i_lnT_00) = s% d_epsnuc_dlnT(k)
     253              :             end if
     254              : 
     255        52348 :             non_nuc_neu_ad = 0d0
     256              :             ! for reasons lost in the past, we always time center non_nuc_neu
     257              :             ! change that if you are feeling lucky.
     258        52348 :             non_nuc_neu_ad%val = 0.5d0*(s% non_nuc_neu_start(k) + s% non_nuc_neu(k))
     259        52348 :             non_nuc_neu_ad%d1Array(i_lnd_00) = 0.5d0*s% d_nonnucneu_dlnd(k)
     260        52348 :             non_nuc_neu_ad%d1Array(i_lnT_00) = 0.5d0*s% d_nonnucneu_dlnT(k)
     261              : 
     262        52348 :             extra_heat_ad = s% extra_heat(k)
     263              : 
     264              :             ! other = eps_WD_sedimentation + eps_diffusion + eps_pre_mix + eps_phase_separation
     265              :             ! no partials for any of these
     266        52348 :             others_ad = 0d0
     267        52348 :             if (s% do_element_diffusion) then
     268            0 :                if (s% do_WD_sedimentation_heating) then
     269            0 :                   others_ad%val = others_ad%val + s% eps_WD_sedimentation(k)
     270            0 :                else if (s% do_diffusion_heating) then
     271            0 :                   others_ad%val = others_ad%val + s% eps_diffusion(k)
     272              :                end if
     273              :             end if
     274        52348 :             if (s% do_conv_premix .and. s% do_premix_heating) &
     275            0 :                others_ad%val = others_ad%val + s% eps_pre_mix(k)
     276        52348 :             if (s% do_phase_separation .and. s% do_phase_separation_heating) &
     277            0 :                others_ad%val = others_ad%val + s% eps_phase_separation(k)
     278              : 
     279        52348 :             Eq_ad = 0d0
     280        52348 :             if (s% RSP2_flag) then
     281            0 :                Eq_ad = s% Eq_ad(k)  ! compute_Eq_cell(s, k, ierr)
     282            0 :                if (ierr /= 0) return
     283              :             else if (s% TDC_alpha_M >0d0 .and. s% MLT_option == 'TDC' .and. &
     284        52348 :                s% TDC_include_eturb_in_energy_equation .and. (s% v_flag .or. s% u_flag)) then
     285            0 :                 if (k < s% nz) then
     286              :                   Eq_ad = 0.5d0*(compute_tdc_Eq_div_w_face(s, k, ierr)*s% mlt_vc_ad(k) + &
     287            0 :                      shift_p1(compute_tdc_Eq_div_w_face(s, k+1, ierr))*shift_p1(s% mlt_vc_ad(k+1)))/sqrt_2_div_3
     288              :                 else ! center cell is 0 at inner face
     289            0 :                      Eq_ad = 0.5d0*compute_tdc_Eq_div_w_face(s, k, ierr)*s% mlt_vc_ad(k)/sqrt_2_div_3
     290              :                 end if
     291            0 :                 if (ierr /= 0) return
     292              :             end if
     293              : 
     294        52348 :             call setup_RTI_diffusion(RTI_diffusion_ad)
     295              : 
     296        52348 :             drag_energy = 0d0
     297        52348 :             s% FdotV_drag_energy(k) = 0
     298        52348 :             if (k /= s% nz) then
     299              :                if ((s% q(k) > s% min_q_for_drag) .and. &
     300        52304 :                     (s% drag_coefficient > 0) .and. &
     301              :                     s% use_drag_energy) then
     302            0 :                   v_00 = wrap_v_00(s,k)
     303            0 :                   drag_force = s% drag_coefficient*v_00/s% dt
     304            0 :                   drag_energy = 0.5d0*v_00*drag_force
     305            0 :                   s% FdotV_drag_energy(k) = drag_energy%val
     306              :                ! drag energy for outer half-cell.   the 0.5d0 is for dm/2
     307              :                end if
     308              :                if ((s% q(k+1) > s% min_q_for_drag) .and. &
     309        52304 :                     (s% drag_coefficient > 0) .and. &
     310              :                     s% use_drag_energy) then
     311            0 :                   v_p1 = wrap_v_p1(s,k)
     312            0 :                   drag_force = s% drag_coefficient*v_p1/s% dt
     313            0 :                   drag_energy = drag_energy + 0.5d0*v_p1*drag_force
     314            0 :                   s% FdotV_drag_energy(k) = drag_energy%val
     315              :                ! drag energy for inner half-cell.   the 0.5d0 is for dm/2
     316              :                end if
     317              :             end if
     318              : 
     319        52348 :             sources_sum_ad = eps_nuc_ad
     320        52348 :             sources_sum_ad = sources_sum_ad - non_nuc_neu_ad
     321        52348 :             sources_sum_ad = sources_sum_ad + extra_heat_ad
     322        52348 :             sources_sum_ad = sources_sum_ad + Eq_ad
     323        52348 :             sources_sum_ad = sources_sum_ad + RTI_diffusion_ad
     324        52348 :             sources_sum_ad = sources_sum_ad + drag_energy
     325              :             sources_ad = sources_sum_ad
     326              : 
     327        52348 :             sources_ad%val = sources_ad%val + s% irradiation_heat(k)
     328              : 
     329        52348 :             if (s% mstar_dot /= 0d0) sources_ad%val = sources_ad%val + s% eps_mdot(k)
     330              : 
     331              :          end subroutine setup_sources_and_others
     332              : 
     333        52348 :          subroutine setup_RTI_diffusion(diffusion_eps_ad)
     334              :             type(auto_diff_real_star_order1), intent(out) :: diffusion_eps_ad
     335              :             real(dp) :: diffusion_factor, emin_start, sigp1, sig00
     336              :             logical :: do_diffusion
     337              :             type(auto_diff_real_star_order1) :: &
     338              :                e_m1, e_00, e_p1, diffusion_eps_in, diffusion_eps_out
     339              :             include 'formats'
     340        52348 :             diffusion_factor = s% dedt_RTI_diffusion_factor
     341        52348 :             do_diffusion = s% RTI_flag .and. diffusion_factor > 0d0
     342              :             if (.not. do_diffusion) then
     343        52348 :                diffusion_eps_ad = 0d0
     344              :             else
     345            0 :                if (k < s% nz) then
     346            0 :                   if (s% alpha_RTI(k) > 1d-10 .and. k > 1) then
     347              :                      emin_start = min( &
     348            0 :                         s% energy_start(k+1), s% energy_start(k), s% energy_start(k-1))
     349            0 :                      if (emin_start < 5d0*s% RTI_energy_floor) then
     350              :                         diffusion_factor = diffusion_factor* &
     351            0 :                            (1d0 + (5d0*s% RTI_energy_floor - emin_start)/emin_start)
     352              :                      end if
     353              :                   end if
     354            0 :                   sigp1 = diffusion_factor*s% sig_RTI(k+1)
     355            0 :                   e_p1 = wrap_e_p1(s,k)
     356              :                else
     357            0 :                   sigp1 = 0
     358            0 :                   e_p1 = 0d0
     359              :                end if
     360            0 :                if (k > 1) then
     361            0 :                   sig00 = diffusion_factor*s% sig_RTI(k)
     362            0 :                   e_m1 = wrap_e_m1(s,k)
     363              :                else
     364            0 :                   sig00 = 0
     365            0 :                   e_m1 = 0
     366              :                end if
     367            0 :                e_00 = wrap_e_00(s,k)
     368            0 :                diffusion_eps_in = sigp1*(e_p1 - e_00)/dm
     369            0 :                diffusion_eps_out = sig00*(e_00 - e_m1)/dm
     370            0 :                diffusion_eps_ad = diffusion_eps_in - diffusion_eps_out
     371              :             end if
     372        52348 :             s% dedt_RTI(k) = diffusion_eps_ad%val
     373        52348 :          end subroutine setup_RTI_diffusion
     374              : 
     375        52348 :          subroutine setup_d_turbulent_energy_dt(ierr)
     376              :             use const_def, only: sqrt_2_div_3
     377              :             integer, intent(out) :: ierr
     378              :             type(auto_diff_real_star_order1) :: TDC_eturb_cell
     379              :             real (dp) :: TDC_eturb_cell_start
     380              :             include 'formats'
     381        52348 :             ierr = 0
     382        52348 :             if (s% RSP2_flag) then
     383            0 :                d_turbulent_energy_dt_ad = (wrap_etrb_00(s,k) - get_etrb_start(s,k))/dt
     384        52348 :             else if (s% MLT_option == 'TDC' .and. s% TDC_include_eturb_in_energy_equation) then
     385              :                ! write a wrapper for this.
     386            0 :                   if (k < s% nz) then
     387            0 :                      if (s% okay_to_set_mlt_vc) then ! have mlt_vc_old
     388              :                         TDC_eturb_cell_start = 0.75d0*(pow2(s% mlt_vc_old(k)) + &
     389            0 :                            pow2(s% mlt_vc_old(k+1)))
     390              :                      else
     391            0 :                         TDC_eturb_cell_start = 0d0
     392              :                      end if
     393              :                      TDC_eturb_cell = 0.75d0*(pow2(s% mlt_vc_ad(k)) + &
     394            0 :                         pow2(shift_p1(s% mlt_vc_ad(k+1))))
     395              :                   else ! center cell averaged with 0 for inner face
     396            0 :                      if (s% okay_to_set_mlt_vc) then ! have mlt_vc_old
     397            0 :                         TDC_eturb_cell_start = 0.75d0*pow2(s% mlt_vc_old(k))
     398              :                      else
     399            0 :                         TDC_eturb_cell_start = 0d0
     400              :                      end if
     401            0 :                      TDC_eturb_cell = 0.75d0*pow2(s% mlt_vc_ad(k))
     402              :                   end if
     403            0 :                d_turbulent_energy_dt_ad = (TDC_eturb_cell - TDC_eturb_cell_start)/dt
     404              :             else
     405        52348 :                d_turbulent_energy_dt_ad = 0d0
     406              :             end if
     407        52348 :             s% detrbdt(k) = d_turbulent_energy_dt_ad%val
     408        52348 :          end subroutine setup_d_turbulent_energy_dt
     409              : 
     410        52348 :          subroutine setup_eps_grav(ierr)
     411              :             integer, intent(out) :: ierr
     412              :             include 'formats'
     413        52348 :             ierr = 0
     414              : 
     415        52348 :             if (s% u_flag) then  ! for now, assume u_flag means no eps_grav
     416            0 :                eps_grav_form = .false.
     417            0 :                return
     418              :             end if
     419              : 
     420              :             ! value from checking s% energy_eqn_option in hydro_eqns.f90
     421        52348 :             eps_grav_form = s% eps_grav_form_for_energy_eqn
     422              : 
     423        52348 :             if (.not. eps_grav_form) then  ! check if want it true
     424        52348 :                if (s% doing_relax .and. s% no_dedt_form_during_relax) eps_grav_form = .true.
     425              :             end if
     426              : 
     427        52348 :             if (eps_grav_form) then
     428            0 :                if (s% RSP2_flag) then
     429            0 :                   call mesa_error(__FILE__,__LINE__,'cannot use eps_grav with et yet.  fix energy eqn.')
     430              :                end if
     431            0 :                call eval_eps_grav_and_partials(s, k, ierr)  ! get eps_grav info
     432            0 :                if (ierr /= 0) then
     433            0 :                   if (s% report_ierr) write(*,2) 'failed in eval_eps_grav_and_partials', k
     434            0 :                   return
     435              :                end if
     436            0 :                eps_grav_ad = s% eps_grav_ad(k)
     437              :             end if
     438              : 
     439              :          end subroutine setup_eps_grav
     440              : 
     441        52348 :          subroutine setup_de_dt_and_friends(ierr)
     442              :             use star_utils, only: get_dke_dt_dpe_dt
     443              :             integer, intent(out) :: ierr
     444              :             real(dp) :: dke_dt, d_dkedt_dv00, d_dkedt_dvp1, &
     445              :                dpe_dt, d_dpedt_dlnR00, d_dpedt_dlnRp1, &
     446              :                de_dt, d_de_dt_dlnd, d_de_dt_dlnT
     447              :             include 'formats'
     448        52348 :             ierr = 0
     449              : 
     450        52348 :             dke_dt = 0d0; d_dkedt_dv00 = 0d0; d_dkedt_dvp1 = 0d0
     451        52348 :             dpe_dt = 0d0; d_dpedt_dlnR00 = 0d0; d_dpedt_dlnRp1 = 0d0
     452        52348 :             de_dt = 0d0; d_de_dt_dlnd = 0d0; d_de_dt_dlnT = 0d0
     453              : 
     454        52348 :             if (.not. eps_grav_form) then
     455              : 
     456        52348 :                de_dt = (s% energy(k) - s% energy_start(k))/dt
     457        52348 :                d_de_dt_dlnd = s% dE_dRho_for_partials(k)*s% rho(k)/dt
     458        52348 :                d_de_dt_dlnT = s% Cv_for_partials(k)*s% T(k)/dt
     459        52348 :                de_dt_ad = 0d0
     460        52348 :                de_dt_ad%val = de_dt
     461        52348 :                de_dt_ad%d1Array(i_lnd_00) = d_de_dt_dlnd
     462        52348 :                de_dt_ad%d1Array(i_lnT_00) = d_de_dt_dlnT
     463              : 
     464              :                call get_dke_dt_dpe_dt(s, k, dt, &
     465              :                   dke_dt, d_dkedt_dv00, d_dkedt_dvp1, &
     466        52348 :                   dpe_dt, d_dpedt_dlnR00, d_dpedt_dlnRp1, ierr)
     467        52348 :                if (ierr /= 0) then
     468            0 :                   if (s% report_ierr) write(*,2) 'failed in get_dke_dt_dpe_dt', k
     469            0 :                   return
     470              :                end if
     471        52348 :                dke_dt_ad = 0d0
     472        52348 :                dke_dt_ad%val = dke_dt
     473        52348 :                dke_dt_ad%d1Array(i_v_00) = d_dkedt_dv00
     474        52348 :                dke_dt_ad%d1Array(i_v_p1) = d_dkedt_dvp1
     475              : 
     476        52348 :                dpe_dt_ad = 0d0
     477        52348 :                dpe_dt_ad%val = dpe_dt
     478        52348 :                dpe_dt_ad%d1Array(i_lnR_00) = d_dpedt_dlnR00
     479        52348 :                dpe_dt_ad%d1Array(i_lnR_p1) = d_dpedt_dlnRp1
     480              : 
     481              :             end if
     482              : 
     483        52348 :             s% dkedt(k) = dke_dt
     484        52348 :             s% dpedt(k) = dpe_dt
     485        52348 :             s% dkedt(k) = dke_dt
     486        52348 :             s% dedt(k) = de_dt
     487              : 
     488              :          end subroutine setup_de_dt_and_friends
     489              : 
     490        52348 :          subroutine unpack_res18(species,res18)
     491              :             use star_utils, only: save_eqn_dxa_partials, unpack_residual_partials
     492              :             type(auto_diff_real_star_order1) :: res18
     493              :             integer, intent(in) :: species
     494              :             real(dp) :: dequ
     495              :             integer :: j
     496        52348 :             real(dp), dimension(species) :: dxam1, dxa00, dxap1
     497              :             logical, parameter :: checking = .true.
     498              :             include 'formats'
     499              : 
     500              :             ! do partials wrt composition
     501      1413396 :             dxam1 = 0d0; dxa00 = 0d0; dxap1 = 0d0
     502        52348 :             if (.not. (s% nonlocal_NiCo_decay_heat .or. doing_op_split_burn)) then
     503        52348 :                if (do_chem .and. s% dxdt_nuc_factor > 0d0) then
     504       471132 :                   do j=1,s% species
     505       418784 :                      dequ = scal*s% d_epsnuc_dx(j,k)
     506       418784 :                      if (checking) call check_dequ(dequ,'d_epsnuc_dx')
     507       471132 :                      dxa00(j) = dxa00(j) + dequ
     508              :                   end do
     509              :                end if
     510              :             end if
     511              : 
     512        52348 :             if (.not. eps_grav_form) then
     513       471132 :                do j=1,s% species
     514       418784 :                   dequ = -scal*(s%energy(k)/dt)*s% dlnE_dxa_for_partials(j,k)
     515       418784 :                   if (checking) call check_dequ(dequ,'dlnE_dxa_for_partials')
     516       471132 :                   dxa00(j) = dxa00(j) + dequ
     517              :                end do
     518            0 :             else if (do_chem .and. (.not. doing_op_split_burn) .and. &
     519              :                      (s% dxdt_nuc_factor > 0d0 .or. s% mix_factor > 0d0)) then
     520            0 :                do j=1,s% species
     521            0 :                   dequ = scal*s% d_eps_grav_dx(j,k)
     522            0 :                   if (checking) call check_dequ(dequ,'d_eps_grav_dx')
     523            0 :                   dxa00(j) = dxa00(j) + dequ
     524              :                end do
     525              :             end if
     526              : 
     527       471132 :             do j=1,s% species
     528       418784 :                dequ = -scal*d_dwork_dxa00(j)/dm
     529       418784 :                if (checking) call check_dequ(dequ,'d_dwork_dxa00')
     530       471132 :                dxa00(j) = dxa00(j) + dequ
     531              :             end do
     532        52348 :             if (k > 1) then
     533       470736 :                do j=1,s% species
     534       418432 :                   dequ = -scal*d_dwork_dxam1(j)/dm
     535       418432 :                   if (checking) call check_dequ(dequ,'d_dwork_dxam1')
     536       470736 :                   dxam1(j) = dxam1(j) + dequ
     537              :                end do
     538              :             end if
     539        52348 :             if (k < nz) then
     540       470736 :                do j=1,s% species
     541       418432 :                   dequ = -scal*d_dwork_dxap1(j)/dm
     542       418432 :                   if (checking) call check_dequ(dequ,'d_dwork_dxap1')
     543       470736 :                   dxap1(j) = dxap1(j) + dequ
     544              :                end do
     545              :             end if
     546              : 
     547              :             call save_eqn_dxa_partials(&
     548        52348 :                s, k, nvar, i_dlnE_dt, species, dxam1, dxa00, dxap1, 'get1_energy_eqn', ierr)
     549              : 
     550              :             call unpack_residual_partials(s, k, nvar, i_dlnE_dt, &
     551        52348 :                res18, d_dm1, d_d00, d_dp1)
     552              : 
     553        52348 :          end subroutine unpack_res18
     554              : 
     555      2093216 :          subroutine check_dequ(dequ, str)
     556              :             real(dp), intent(in) :: dequ
     557              :             character (len=*), intent(in) :: str
     558              :             include 'formats'
     559      2093216 :             if (is_bad(dequ)) then
     560            0 : !$omp critical (hydro_energy_crit2)
     561            0 :                ierr = -1
     562            0 :                if (s% report_ierr) then
     563            0 :                   write(*,2) 'get1_energy_eqn: bad ' // trim(str), k, dequ
     564              :                end if
     565            0 :                if (s% stop_for_bad_nums) call mesa_error(__FILE__,__LINE__,'get1_energy_eqn')
     566              : !$omp end critical (hydro_energy_crit2)
     567            0 :                return
     568              :             end if
     569              :          end subroutine check_dequ
     570              : 
     571              :          subroutine unpack1(j, dvar_m1, dvar_00, dvar_p1)
     572              :             integer, intent(in) :: j
     573              :             real(dp), intent(in) :: dvar_m1, dvar_00, dvar_p1
     574              :             d_dm1(j) = dvar_m1
     575              :             d_d00(j) = dvar_00
     576              :             d_dp1(j) = dvar_p1
     577              :          end subroutine unpack1
     578              : 
     579              :       end subroutine get1_energy_eqn
     580              : 
     581              : 
     582        52348 :       subroutine eval_dwork(s, k, skip_P, dwork_ad, dwork, &
     583        52348 :             d_dwork_dxam1, d_dwork_dxa00, d_dwork_dxap1, ierr)
     584              :          use auto_diff_support
     585              :          use star_utils, only: calc_Ptot_ad_tw
     586              :          type (star_info), pointer :: s
     587              :          integer, intent(in) :: k
     588              :          logical, intent(in) :: skip_P
     589              :          type(auto_diff_real_star_order1), intent(out) :: dwork_ad
     590              :          real(dp), intent(out) :: dwork
     591              :          real(dp), intent(out), dimension(s% species) :: &
     592              :             d_dwork_dxam1, d_dwork_dxa00, d_dwork_dxap1
     593              :          integer, intent(out) :: ierr
     594              : 
     595              :          real(dp) :: work_00, work_p1
     596              :          real(dp), dimension(s% species) :: &
     597       104696 :             d_work_00_dxa00, d_work_00_dxam1, &
     598            0 :             d_work_p1_dxap1, d_work_p1_dxa00
     599              :          type(auto_diff_real_star_order1) :: work_00_ad, work_p1_ad
     600              :          logical :: test_partials
     601              :          integer :: j
     602              :          include 'formats'
     603              :          ierr = 0
     604              : 
     605              :          call eval1_work(s, k, skip_P, &
     606        52348 :             work_00_ad, work_00, d_work_00_dxa00, d_work_00_dxam1, ierr)
     607        52348 :          if (ierr /= 0) return
     608              :          call eval1_work(s, k+1, skip_P, &
     609        52348 :             work_p1_ad, work_p1, d_work_p1_dxap1, d_work_p1_dxa00, ierr)
     610        52348 :          if (ierr /= 0) return
     611        52348 :          work_p1_ad = shift_p1(work_p1_ad)  ! shift the partials
     612        52348 :          dwork_ad = work_00_ad - work_p1_ad
     613        52348 :          dwork = dwork_ad%val
     614       471132 :          do j=1,s% species
     615       418784 :             d_dwork_dxam1(j) = d_work_00_dxam1(j)
     616       418784 :             d_dwork_dxa00(j) = d_work_00_dxa00(j) - d_work_p1_dxa00(j)
     617       471132 :             d_dwork_dxap1(j) = -d_work_p1_dxap1(j)
     618              :          end do
     619              : 
     620              :          !test_partials = (k == s% solver_test_partials_k)
     621        52348 :          test_partials = .false.
     622              : 
     623              :          if (test_partials) then
     624              :             s% solver_test_partials_val = 0
     625              :             s% solver_test_partials_var = 0
     626              :             s% solver_test_partials_dval_dx = 0
     627              :             write(*,*) 'eval_dwork', s% solver_test_partials_var
     628              :          end if
     629              : 
     630              :       end subroutine eval_dwork
     631              : 
     632              : 
     633              :       ! ergs/s at face(k)
     634       104696 :       subroutine eval1_work(s, k, skip_Peos, &
     635       104696 :             work_ad, work, d_work_dxa00, d_work_dxam1, ierr)
     636              :          use star_utils, only: get_Pvsc_ad, calc_Ptrb_ad_tw, get_rho_face
     637              :          use accurate_sum_auto_diff_star_order1
     638              :          use auto_diff_support
     639              :          type (star_info), pointer :: s
     640              :          integer, intent(in) :: k
     641              :          logical, intent(in) :: skip_Peos
     642              :          type(auto_diff_real_star_order1), intent(out) :: work_ad
     643              :          real(dp), intent(out) :: work
     644              :          real(dp), dimension(s% species), intent(out) :: &
     645              :             d_work_dxa00, d_work_dxam1
     646              :          integer, intent(out) :: ierr
     647              :          real(dp) :: alfa, beta, P_theta, Av_face
     648           44 :          real(dp), dimension(s% species) :: d_Pface_dxa00, d_Pface_dxam1
     649              :          type(auto_diff_real_star_order1) :: &
     650              :             P_face_ad, A_times_v_face_ad, mlt_Pturb_ad, &
     651              :             PtrbR_ad, PtrbL_ad, PvscL_ad, PvscR_ad, Ptrb_div_etrb, PL_ad, PR_ad, &
     652              :             Peos_ad, Ptrb_ad, Pvsc_ad, extra_P
     653              :          type(accurate_auto_diff_real_star_order1) :: P_face_sum_ad
     654              :          logical :: test_partials
     655              :          integer :: j
     656              :          include 'formats'
     657       104696 :          ierr = 0
     658              : 
     659       942264 :          d_work_dxa00 = 0d0
     660       942264 :          d_work_dxam1 = 0d0
     661       104696 :          if (k > s% nz .or. (s% dt <= 0d0 .and. .not. (s% v_flag .or. s% u_flag))) then
     662           44 :             work_ad = 0d0
     663           44 :             if (k == s% nz+1) then
     664           44 :                work = pi4*pow2(s% r_center)*s% Peos_start(s% nz)*s% v_center
     665           44 :                s% work_inward_at_center = work
     666           44 :                if (is_bad(work)) then
     667            0 :                   write(*,2) 'work_inward_at_center', s% model_number, work
     668            0 :                   write(*,2) 'Peos_start', s% model_number, s% Peos_start(s% nz)
     669            0 :                   write(*,2) 'v_center', s% model_number, s% v_center
     670            0 :                   write(*,2) 'r_center', s% model_number, s% r_center
     671            0 :                   call mesa_error(__FILE__,__LINE__,'eval1_work')
     672              :                end if
     673              :             end if
     674           44 :             work_ad%val = work
     675           44 :             return
     676              :          end if
     677              : 
     678       104652 :          call eval1_A_times_v_face_ad(s, k, A_times_v_face_ad, ierr)
     679       104652 :          if (ierr /= 0) return
     680              : 
     681       104652 :          if (k > 1) then
     682       104608 :             alfa = s% dq(k-1)/(s% dq(k-1) + s% dq(k))
     683              :          else
     684           44 :             alfa = 1d0
     685              :          end if
     686       104652 :          beta = 1d0 - alfa
     687              : 
     688              :          if (s% using_velocity_time_centering .and. &
     689       104652 :                   s% include_P_in_velocity_time_centering .and. &
     690              :                   s% lnT(k)/ln10 <= s% max_logT_for_include_P_and_L_in_velocity_time_centering) then
     691            0 :             P_theta = s% P_theta_for_velocity_time_centering
     692              :          else
     693       104652 :             P_theta = 1d0 ! try 1 - q(k)
     694              :          end if
     695              : 
     696       104652 :          if (s% u_flag) then
     697            0 :             P_face_ad = P_theta*s% P_face_ad(k) + (1d0-P_theta)*s% P_face_start(k)
     698            0 :             d_Pface_dxa00 = 0d0
     699            0 :             d_Pface_dxam1 = 0d0
     700              :          else  ! set P_ad
     701       941868 :             d_Pface_dxa00 = 0d0
     702       941868 :             d_Pface_dxam1 = 0d0
     703       104652 :             if (skip_Peos) then
     704            0 :                Peos_ad = 0d0
     705              :             else
     706       104652 :                if (k > 1) then
     707       104608 :                   PR_ad = P_theta*wrap_Peos_m1(s,k) + (1d0-P_theta)*s% Peos_start(k-1)
     708              :                else
     709           44 :                   PR_ad = 0d0
     710              :                end if
     711       104652 :                PL_ad = P_theta*wrap_Peos_00(s,k) + (1d0-P_theta)*s% Peos_start(k)
     712       104652 :                Peos_ad = alfa*PL_ad + beta*PR_ad
     713       104652 :                if (k > 1) then
     714       941472 :                   do j=1,s% species
     715              :                      d_Pface_dxa00(j) = &
     716       941472 :                         alfa*s% dlnPeos_dxa_for_partials(j,k)*P_theta*s% Peos(k)
     717              :                   end do
     718       941472 :                   do j=1,s% species
     719              :                      d_Pface_dxam1(j) = &
     720       941472 :                         beta*s% dlnPeos_dxa_for_partials(j,k-1)*P_theta*s% Peos(k-1)
     721              :                   end do
     722              :                else  ! k == 1
     723          396 :                   do j=1,s% species
     724              :                      d_Pface_dxa00(j) = &
     725          396 :                         s% dlnPeos_dxa_for_partials(j,k)*P_theta*s% Peos(k)
     726              :                   end do
     727              :                end if
     728              :             end if
     729              : 
     730              :             ! set Pvsc_ad
     731       104652 :             if (.not. s% use_Pvsc_art_visc) then
     732       104652 :                Pvsc_ad = 0d0
     733              :             else
     734            0 :                if (k > 1) then
     735            0 :                   call get_Pvsc_ad(s, k-1, PvscR_ad, ierr)
     736            0 :                   if (ierr /= 0) return
     737            0 :                   PvscR_ad = shift_m1(PvscR_ad)
     738            0 :                   if (s% include_P_in_velocity_time_centering .and. &
     739              :                       s% lnT(k)/ln10 <= s% max_logT_for_include_P_and_L_in_velocity_time_centering) &
     740            0 :                      PvscR_ad = 0.5d0*(PvscR_ad + s% Pvsc_start(k-1))
     741              :                else
     742            0 :                   PvscR_ad = 0d0
     743              :                end if
     744            0 :                call get_Pvsc_ad(s, k, PvscL_ad, ierr)
     745            0 :                if (ierr /= 0) return
     746            0 :                if (s% include_P_in_velocity_time_centering .and. &
     747              :                    s% lnT(k)/ln10 <= s% max_logT_for_include_P_and_L_in_velocity_time_centering) &
     748            0 :                   PvscL_ad = 0.5d0*(PvscL_ad + s% Pvsc_start(k))
     749            0 :                Pvsc_ad = alfa*PvscL_ad + beta*PvscR_ad
     750              :             end if
     751              : 
     752              :             ! set Ptrb_ad
     753       104652 :             if (.not. s% RSP2_flag) then
     754       104652 :                Ptrb_ad = 0d0
     755              :             else
     756            0 :                if (k > 1) then
     757            0 :                   call calc_Ptrb_ad_tw(s, k-1, PtrbR_ad, Ptrb_div_etrb, ierr)
     758            0 :                   if (ierr /= 0) return
     759            0 :                   PtrbR_ad = shift_m1(PtrbR_ad)
     760              :                else
     761            0 :                   PtrbR_ad = 0d0
     762              :                end if
     763            0 :                call calc_Ptrb_ad_tw(s, k, PtrbL_ad, Ptrb_div_etrb, ierr)
     764            0 :                if (ierr /= 0) return
     765            0 :                Ptrb_ad = alfa*PtrbL_ad + beta*PtrbR_ad
     766              :             end if
     767              : 
     768              :             ! set extra_P
     769       104652 :             if (.not. s% use_other_pressure) then
     770       104652 :                extra_P = 0d0
     771            0 :             else if (k > 1) then
     772              :                ! my_val_m1 = shift_m1(get_my_val(s,k-1)) for use in terms going into equation at k
     773            0 :                extra_P = alfa*s% extra_pressure(k) + beta * shift_m1(s%extra_pressure(k-1))
     774              :             else
     775            0 :                extra_P = s% extra_pressure(k)
     776              :             end if
     777              : 
     778              :             ! set mlt_Pturb_ad
     779       104652 :             mlt_Pturb_ad = 0d0
     780       104652 :             if (s% mlt_Pturb_factor > 0d0 .and. s% mlt_vc_old(k) > 0d0) &
     781            0 :                mlt_Pturb_ad = s% mlt_Pturb_factor*pow2(s% mlt_vc_old(k))*get_rho_face(s,k)/3d0
     782              : 
     783       104652 :             P_face_sum_ad = Peos_ad
     784       104652 :             P_face_sum_ad = P_face_sum_ad + Pvsc_ad
     785       104652 :             P_face_sum_ad = P_face_sum_ad + Ptrb_ad
     786       104652 :             P_face_sum_ad = P_face_sum_ad + mlt_Pturb_ad
     787       104652 :             P_face_sum_ad = P_face_sum_ad + extra_P
     788       104652 :             P_face_ad = P_face_sum_ad
     789              : 
     790              :          end if
     791              : 
     792       104652 :          work_ad = A_times_v_face_ad*P_face_ad
     793       104652 :          work = work_ad%val
     794              : 
     795       104652 :          if (k == 1) s% work_outward_at_surface = work
     796              : 
     797       104652 :          Av_face = A_times_v_face_ad%val
     798       941868 :          do j=1,s% species
     799       837216 :             d_work_dxa00(j) = Av_face*d_Pface_dxa00(j)
     800       941868 :             d_work_dxam1(j) = Av_face*d_Pface_dxam1(j)
     801              :          end do
     802              : 
     803              :          !test_partials = (k == s% solver_test_partials_k)
     804       104652 :          test_partials = .false.
     805              : 
     806              :          if (test_partials) then
     807              :             s% solver_test_partials_val = 0
     808              :             s% solver_test_partials_var = 0
     809              :             s% solver_test_partials_dval_dx = 0
     810              :             write(*,*) 'eval1_work', s% solver_test_partials_var
     811              :          end if
     812              : 
     813              :       end subroutine eval1_work
     814              : 
     815              : 
     816       104652 :       subroutine eval1_A_times_v_face_ad(s, k, A_times_v_face_ad, ierr)
     817              :          use star_utils, only: get_area_info_opt_time_center
     818              :          type (star_info), pointer :: s
     819              :          integer, intent(in) :: k
     820              :          type(auto_diff_real_star_order1), intent(out) :: A_times_v_face_ad
     821              :          integer, intent(out) :: ierr
     822              :          type(auto_diff_real_star_order1) :: A_ad, inv_R2, u_face_ad
     823              :          include 'formats'
     824              : 
     825              :          ierr = 0
     826       104652 :          call get_area_info_opt_time_center(s, k, A_ad, inv_R2, ierr)
     827       104652 :          if (ierr /= 0) return
     828              : 
     829       104652 :          u_face_ad = 0d0
     830       104652 :          if (s% v_flag) then
     831            0 :             u_face_ad%val = s% vc(k)
     832            0 :             u_face_ad%d1Array(i_v_00) = s% d_vc_dv
     833       104652 :          else if (s% u_flag) then
     834            0 :             u_face_ad = s% u_face_ad(k)
     835            0 :             if (s% using_velocity_time_centering) &
     836            0 :                u_face_ad = 0.5d0*(u_face_ad + s% u_face_start(k))
     837       104652 :          else if (s% using_velocity_time_centering) then
     838            0 :             u_face_ad%val = 0.5d0*(s% r(k) - s% r_start(k))/s% dt
     839            0 :             u_face_ad%d1Array(i_lnR_00) = 0.5d0*s% r(k)/s% dt
     840              :          else
     841       104652 :             u_face_ad%val = (s% r(k) - s% r_start(k))/s% dt
     842       104652 :             u_face_ad%d1Array(i_lnR_00) = s% r(k)/s% dt
     843              :          end if
     844              : 
     845       104652 :          A_times_v_face_ad = A_ad*u_face_ad
     846              : 
     847              :       end subroutine eval1_A_times_v_face_ad
     848              : 
     849              : 
     850            0 :       subroutine eval_simple_PdV_work( &
     851            0 :             s, k, skip_P, dwork_ad, dwork, d_dwork_dxa00, ierr)
     852              :          use auto_diff_support
     853              :          use star_utils, only: calc_Ptot_ad_tw
     854              :          type (star_info), pointer :: s
     855              :          integer, intent(in) :: k
     856              :          logical, intent(in) :: skip_P
     857              :          type(auto_diff_real_star_order1), intent(out) :: dwork_ad
     858              :          real(dp), intent(out) :: dwork
     859              :          real(dp), intent(out), dimension(s% species) :: d_dwork_dxa00
     860              :          integer, intent(out) :: ierr
     861              : 
     862              :          type(auto_diff_real_star_order1) :: &
     863              :             Av_face00_ad, Av_facep1_ad, Ptot_ad, dV
     864            0 :          real(dp), dimension(s% species) :: d_Ptot_dxa
     865              :          real(dp) :: Av_face00, Av_facep1
     866              :          logical :: include_mlt_Pturb
     867              :          integer :: j
     868              : 
     869              :          include 'formats'
     870              :          ierr = 0
     871              : 
     872              :          ! dV = 1/rho - 1/rho_start
     873            0 :          call eval1_A_times_v_face_ad(s, k, Av_face00_ad, ierr)
     874            0 :          if (ierr /= 0) return
     875            0 :          if (k < s% nz) then
     876            0 :             call eval1_A_times_v_face_ad(s, k+1, Av_facep1_ad, ierr)
     877            0 :             if (ierr /= 0) return
     878            0 :             Av_facep1_ad = shift_p1(Av_facep1_ad)
     879              :          else
     880            0 :             Av_facep1_ad = 0d0
     881            0 :             Av_facep1_ad%val = 4*pi*pow2(s% r_center)*s% v_center
     882              :          end if
     883            0 :          Av_face00 = Av_face00_ad%val
     884            0 :          Av_facep1 = Av_facep1_ad%val
     885            0 :          dV = Av_face00_ad - Av_facep1_ad
     886              : 
     887              :          include_mlt_Pturb = s% mlt_Pturb_factor > 0d0 &
     888            0 :             .and. s% mlt_vc_old(k) > 0d0 .and. k > 1
     889              : 
     890              :          call calc_Ptot_ad_tw( &
     891            0 :             s, k, skip_P, .not. include_mlt_Pturb, Ptot_ad, d_Ptot_dxa, ierr)
     892            0 :          if (ierr /= 0) return
     893              : 
     894            0 :          do j=1,s% species
     895            0 :             d_dwork_dxa00(j) = d_Ptot_dxa(j)*(Av_face00 - Av_facep1)
     896              :          end do
     897            0 :          if (k == 1) s% work_outward_at_surface = Ptot_ad%val*Av_face00
     898              : 
     899            0 :          dwork_ad = Ptot_ad*dV
     900            0 :          dwork = dwork_ad%val
     901              : 
     902              :       end subroutine eval_simple_PdV_work
     903              : 
     904              :       end module hydro_energy
        

Generated by: LCOV version 2.0-1