LCOV - code coverage report
Current view: top level - star/private - struct_burn_mix.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 38.5 % 538 207
Test Date: 2025-10-25 19:18:45 Functions: 64.7 % 17 11

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010  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 struct_burn_mix
      21              : 
      22              :       use star_private_def
      23              :       use const_def, only: dp, i8, ln10, secyer, lsun
      24              :       use utils_lib, only: is_bad
      25              : 
      26              :       implicit none
      27              : 
      28              :       private
      29              :       public :: do_struct_burn_mix
      30              : 
      31              :       contains
      32              : 
      33           11 :       integer function do_struct_burn_mix(s, skip_global_corr_coeff_limit)
      34              :          use mix_info, only: get_convection_sigmas
      35              :          use rates_def, only: num_rvs
      36              :          use hydro_vars, only: set_vars_if_needed
      37              :          use star_utils, only: start_time, update_time
      38              : 
      39              :          type (star_info), pointer :: s
      40              :          logical, intent(in) :: skip_global_corr_coeff_limit
      41              : 
      42              :          integer :: nz, nvar, species, ierr, k
      43              :          integer(i8) :: time0
      44              :          logical :: do_chem
      45           11 :          real(dp) :: dt, tol_correction_norm, tol_max_correction, total
      46              : 
      47              :          include 'formats'
      48              : 
      49           11 :          ierr = 0
      50           11 :          s% non_epsnuc_energy_change_from_split_burn = 0d0
      51           11 :          dt = s% dt
      52              : 
      53           11 :          if (s% rsp_flag) then
      54            0 :             do_struct_burn_mix = do_rsp_step(s,dt)
      55              :             s% total_num_solver_iterations = &
      56            0 :                s% total_num_solver_iterations + s% num_solver_iterations
      57            0 :             s% total_num_solver_calls_made = s% total_num_solver_calls_made + 1
      58            0 :             if (do_struct_burn_mix == keep_going) &
      59              :                s% total_num_solver_calls_converged = &
      60            0 :                   s% total_num_solver_calls_converged + 1
      61            0 :             return
      62              :          end if
      63              : 
      64           11 :          if (s% use_other_before_struct_burn_mix) then
      65            0 :             call s% other_before_struct_burn_mix(s% id, dt, do_struct_burn_mix)
      66            0 :             if (do_struct_burn_mix /= keep_going) return
      67              :          end if
      68              : 
      69           11 :          if (s% doing_timing) call start_time(s, time0, total)
      70              : 
      71           11 :          s% doing_struct_burn_mix = .true.
      72           11 :          nz = s% nz
      73              : 
      74           11 :          species = s% species
      75           11 :          s% num_solver_iterations = 0
      76              : 
      77           11 :          do_struct_burn_mix = retry
      78              : 
      79           11 :          s% do_burn = (s% dxdt_nuc_factor > 0d0)
      80           11 :          s% do_mix = (s% mix_factor > 0d0)
      81              : 
      82           11 :          if (s% op_split_burn) then
      83            0 :             do k=1,nz
      84            0 :                s% burn_num_iters(k) = 0
      85            0 :                if (s% T(k) >= s% op_split_burn_min_T) then
      86            0 :                   s% eps_nuc(k) = 0d0
      87            0 :                   s% d_epsnuc_dlnd(k) = 0d0
      88            0 :                   s% d_epsnuc_dlnT(k) = 0d0
      89            0 :                   s% d_epsnuc_dx(:,k) = 0d0
      90            0 :                   s% eps_nuc_categories(:,k) = 0d0
      91            0 :                   s% dxdt_nuc(:,k) =  0d0
      92            0 :                   s% d_dxdt_nuc_dRho(:,k) =  0d0
      93            0 :                   s% d_dxdt_nuc_dT(:,k) =  0d0
      94            0 :                   s% d_dxdt_nuc_dx(:,:,k) =  0d0
      95            0 :                   s% eps_nuc_neu_total(k) = 0d0
      96              :                end if
      97              :             end do
      98              :          end if
      99              : 
     100           11 :          if (s% do_burn .and. s% op_split_burn) then
     101            0 :             total = 0
     102            0 :             do k=1,s% nz
     103            0 :                total = total - s% energy(k)*s% dm(k)
     104              :             end do
     105            0 :             if (s% trace_evolve) write(*,*) 'call do_burn'
     106            0 :             do_struct_burn_mix = do_burn(s, dt)
     107            0 :             if (do_struct_burn_mix /= keep_going) then
     108            0 :                write(*,2) 'failed in do_burn', s% model_number
     109            0 :                call mesa_error(__FILE__,__LINE__,'do_struct_burn_mix')
     110            0 :                return
     111              :             end if
     112            0 :             call set_vars_if_needed(s, s% dt, 'after do_burn', ierr)
     113            0 :             if (ierr /= 0) return
     114            0 :             do k=1,s% nz
     115            0 :                total = total + s% energy(k)*s% dm(k)
     116              :             end do
     117            0 :             s% non_epsnuc_energy_change_from_split_burn = total
     118            0 :             if (s% trace_evolve) write(*,*) 'done do_burn'
     119              :          end if
     120              : 
     121           11 :          if (s% doing_first_model_of_run) then
     122            1 :             if (s% i_lum /= 0) then
     123            1 :                s% L_phot_old = s% xh(s% i_lum,1)/Lsun
     124              :             else
     125            0 :                s% L_phot_old = 0
     126              :             end if
     127              :          end if
     128              : 
     129           11 :          if (s% do_mix) then
     130           11 :             call get_convection_sigmas(s, dt, ierr)
     131           11 :             if (ierr /= 0) then
     132            0 :                if (s% report_ierr) write(*,*) 'get_convection_sigmas failed'
     133            0 :                return
     134              :             end if
     135              :          else
     136            0 :             s% sig(1:s% nz) = 0
     137              :          end if
     138              : 
     139           11 :          do_chem = (s% do_burn .or. s% do_mix)
     140              :          if (do_chem) then  ! include abundances
     141           11 :             nvar = s% nvar_total
     142              :          else  ! no chem => just do structure
     143            0 :             nvar = s% nvar_hydro
     144              :          end if
     145              : 
     146              :          call set_tol_correction(s, maxval(s% T(1:s% nz)), &
     147        13109 :             tol_correction_norm, tol_max_correction)
     148           11 :          call set_surf_info(s, nvar)
     149              : 
     150           11 :          if (s% w_div_wc_flag) then
     151            0 :             s% xh(s% i_w_div_wc,:s% nz) = s% w_div_w_crit_roche(:s% nz)
     152              :          end if
     153              : 
     154           11 :          if (s% j_rot_flag) then
     155            0 :             s% xh(s% i_j_rot,:s% nz) = s% j_rot(:s% nz)
     156            0 :             s% j_rot_start(:s% nz) = s% j_rot(:s% nz)
     157            0 :             do k=1, s% nz
     158            0 :                s% i_rot_start(k) = s% i_rot(k)% val
     159              :             end do
     160            0 :             s% total_abs_angular_momentum = dot_product(abs(s% j_rot(:s% nz)),s% dm_bar(:s% nz))
     161              :          end if
     162              : 
     163           11 :          call save_start_values(s, ierr)
     164           11 :          if (ierr /= 0) then
     165            0 :             if (s% report_ierr) write(*,*) 'save_start_values failed'
     166            0 :             return
     167              :          end if
     168              : 
     169           11 :          if (s% trace_evolve) write(*,*) 'call solver'
     170              :          do_struct_burn_mix = do_solver_converge( &
     171              :             s, nvar, skip_global_corr_coeff_limit, &
     172           11 :             tol_correction_norm, tol_max_correction)
     173           11 :          if (s% trace_evolve) write(*,*) 'done solver'
     174              : 
     175              :          s% total_num_solver_iterations = &
     176           11 :             s% total_num_solver_iterations + s% num_solver_iterations
     177           11 :          s% total_num_solver_calls_made = s% total_num_solver_calls_made + 1
     178           11 :          if (do_struct_burn_mix == keep_going) &
     179              :             s% total_num_solver_calls_converged = &
     180           11 :                s% total_num_solver_calls_converged + 1
     181           11 :          if (s% doing_relax) then
     182              :             s% total_num_solver_relax_iterations = &
     183            0 :                s% total_num_solver_relax_iterations + s% num_solver_iterations
     184            0 :             s% total_num_solver_relax_calls_made = s% total_num_solver_relax_calls_made + 1
     185            0 :             if (do_struct_burn_mix == keep_going) &
     186              :                s% total_num_solver_relax_calls_converged = &
     187            0 :                   s% total_num_solver_relax_calls_converged + 1
     188              :          end if
     189              : 
     190           11 :          if (do_struct_burn_mix /= keep_going) return
     191              : 
     192           11 :          if (s% rotation_flag) then
     193              :             ! store ST mixing info for time smoothing
     194            0 :             do k=1, s% nz
     195            0 :                s% D_ST_start(k) = s% D_ST(k)
     196            0 :                s% nu_ST_start(k) = s% nu_ST(k)
     197              :             end do
     198            0 :             s% have_ST_start_info = .true.
     199              :          end if
     200              : 
     201           11 :          if (.not. s% j_rot_flag) &
     202           11 :             do_struct_burn_mix = do_mix_omega(s,dt)
     203              : 
     204           11 :          if (s% use_other_after_struct_burn_mix) &
     205            0 :             call s% other_after_struct_burn_mix(s% id, dt, do_struct_burn_mix)
     206              : 
     207           11 :          s% solver_iter = 0  ! to indicate that no longer doing solver iterations
     208           11 :          s% doing_struct_burn_mix = .false.
     209           11 :          if (s% doing_timing) call update_time(s, time0, total, s% time_struct_burn_mix)
     210              : 
     211              :          contains
     212              : 
     213              :          subroutine test(str)
     214           11 :             use chem_def, only: category_name
     215              :             character (len=*), intent(in) :: str
     216              :             include 'formats'
     217              :             integer :: k, i
     218              :             k = s% nz
     219              :             i = maxloc(s% eps_nuc_categories(1:num_categories,k),dim=1)
     220              :             write(*,3) trim(str) // ' eps_nuc_cat ' // trim(category_name(i)), &
     221              :                k, s% model_number, s% eps_nuc_categories(i,k)
     222              :          end subroutine test
     223              : 
     224              :       end function do_struct_burn_mix
     225              : 
     226              : 
     227           11 :       integer function do_mix_omega(s, dt)
     228              :          use solve_omega_mix, only: do_solve_omega_mix
     229              :          use hydro_rotation, only: set_i_rot, set_omega
     230              : 
     231              :          type (star_info), pointer :: s
     232              :          real(dp), intent(in) :: dt
     233              : 
     234           11 :          do_mix_omega = keep_going
     235              : 
     236           11 :          if (s% rotation_flag) then
     237              :             ! After solver is done with the structure, recompute moments of inertia and
     238              :             ! omega before angular momentum mix
     239            0 :             call set_i_rot(s, .false.)
     240            0 :             call set_omega(s, 'struct_burn_mix')
     241            0 :             if (s% premix_omega) then
     242            0 :                do_mix_omega = do_solve_omega_mix(s, 0.5d0*dt)
     243              :             else
     244            0 :                do_mix_omega = do_solve_omega_mix(s, dt)
     245              :             end if
     246            0 :             if (do_mix_omega /= keep_going) return
     247              :          end if
     248              : 
     249           11 :       end function do_mix_omega
     250              : 
     251              : 
     252            0 :       integer function do_rsp_step(s,dt)
     253              :          ! return keep_going, retry, or terminate
     254           11 :          use rsp, only: rsp_one_step
     255              :          type (star_info), pointer :: s
     256              :          real(dp), intent(in) :: dt
     257              :          integer :: ierr
     258            0 :          do_rsp_step = keep_going
     259              :          ierr = 0
     260            0 :          call rsp_one_step(s,ierr)
     261            0 :          if (ierr /= 0) then
     262            0 :             if (s% report_ierr) write(*,*) 'ierr from rsp_one_step'
     263              :             do_rsp_step = retry
     264              :          end if
     265            0 :       end function do_rsp_step
     266              : 
     267              : 
     268           11 :       subroutine save_start_values(s, ierr)
     269            0 :          use hydro_rsp2, only: set_etrb_start_vars
     270              :          use star_utils, only: eval_total_energy_integrals, set_luminosity_by_category, get_Peos_face_val
     271              :          type (star_info), pointer :: s
     272              :          integer, intent(out) :: ierr
     273              :          integer :: k, j
     274              :          include 'formats'
     275           11 :          ierr = 0
     276              : 
     277           11 :          call set_luminosity_by_category(s)
     278              : 
     279        13098 :          do k=1,s% nz
     280       117783 :             do j=1,s% species
     281       117783 :                s% dxdt_nuc_start(j,k) = s% dxdt_nuc(j,k)
     282              :             end do
     283       327186 :             do j=1,num_categories
     284              :                s% luminosity_by_category_start(j,k) = &
     285       327175 :                   s% luminosity_by_category(j,k)
     286              :             end do
     287              :          end do
     288              : 
     289        13098 :          do k=1,s% nz
     290              :             !s% lnT_start(k) = s% lnT(k)
     291              :             !s% T_start(k) set elsewhere
     292              :             !s% lnd_start(k) = s% lnd(k) set elsewhere
     293              :             !s% rho_start(k) = s% rho(k)
     294              :             !s% r_start(k) set elsewhere
     295              :             !s% rmid_start(k) set elsewhere
     296              :             !s% v_start(k) set elsewhere
     297              :             !s% csound_start(k) set elsewhere
     298        13087 :             s% lnPeos_start(k) = s% lnPeos(k)
     299        13087 :             s% Peos_start(k) = s% Peos(k)
     300        13087 :             s% Peos_face_start(k) = get_Peos_face_val(s,k)
     301        13087 :             s% lnPgas_start(k) = s% lnPgas(k)
     302        13087 :             s% energy_start(k) = s% energy(k)
     303        13087 :             s% lnR_start(k) = s% lnR(k)
     304        13087 :             s% u_start(k) = s% u(k)
     305        13087 :             s% u_face_start(k) = 0d0  ! s% u_face_ad(k)%val
     306        13087 :             s% P_face_start(k) = -1d0  ! mark as unset s% P_face_ad(k)%val
     307        13087 :             s% L_start(k) = s% L(k)
     308        13087 :             s% omega_start(k) = s% omega(k)
     309        13087 :             s% ye_start(k) = s% ye(k)
     310        13087 :             s% j_rot_start(k) = s% j_rot(k)
     311        13087 :             s% eps_nuc_start(k) = s% eps_nuc(k)
     312        13087 :             s% non_nuc_neu_start(k) = s% non_nuc_neu(k)
     313        13087 :             s% Pvsc_start(k) = -1d99
     314        13087 :             s% grada_start(k) = s% grada(k)
     315        13087 :             s% chiT_start(k) = s% chiT(k)
     316        13087 :             s% chiRho_start(k) = s% chiRho(k)
     317        13087 :             s% cp_start(k) = s% cp(k)
     318        13087 :             s% Cv_start(k) = s% Cv(k)
     319        13087 :             s% dE_dRho_start(k) = s% dE_dRho(k)
     320        13087 :             s% gam_start(k) = s% gam(k)
     321        13087 :             s% lnS_start(k) = s% lnS(k)
     322        13087 :             s% zbar_start(k) = s% zbar(k)
     323        13087 :             s% mu_start(k) = s% mu(k)
     324        13087 :             s% phase_start(k) = s% phase(k)
     325        13087 :             s% latent_ddlnT_start(k) = s% latent_ddlnT(k)
     326        13087 :             s% latent_ddlnRho_start(k) = s% latent_ddlnRho(k)
     327        13087 :             s% eps_nuc_start(k) = s% eps_nuc(k)
     328        13087 :             s% opacity_start(k) = s% opacity(k)
     329        13098 :             s% m_grav_start(k) = s% m_grav(k)
     330              :          end do
     331              : 
     332           11 :          if (s% RSP2_flag) then
     333            0 :             call set_etrb_start_vars(s,ierr)
     334              :          end if
     335              : 
     336        13098 :          do k=1,s% nz
     337        65446 :             do j=1,s% nvar_hydro
     338        65435 :                s% xh_start(j,k) = s% xh(j,k)
     339              :             end do
     340              :          end do
     341              : 
     342        13098 :          do k=1,s% nz
     343       117794 :             do j=1,s% species
     344       117783 :                s% xa_start(j,k) = s% xa(j,k)
     345              :             end do
     346              :          end do
     347              : 
     348              :          call eval_total_energy_integrals(s, &
     349              :             s% total_internal_energy_start, &
     350              :             s% total_gravitational_energy_start, &
     351              :             s% total_radial_kinetic_energy_start, &
     352              :             s% total_rotational_kinetic_energy_start, &
     353              :             s% total_turbulent_energy_start, &
     354           11 :             s% total_energy_start)
     355              : 
     356           11 :       end subroutine save_start_values
     357              : 
     358              : 
     359           11 :       integer function do_solver_converge( &
     360              :             s, nvar, skip_global_corr_coeff_limit, &
     361              :             tol_correction_norm, tol_max_correction)
     362              :          ! return keep_going, retry, or terminate
     363           11 :          use mtx_lib
     364              :          use mtx_def
     365              :          use num_def
     366              :          use star_utils, only: start_time, update_time
     367              : 
     368              :          type (star_info), pointer :: s
     369              :          integer, intent(in) :: nvar
     370              :          logical, intent(in) :: skip_global_corr_coeff_limit
     371              :          real(dp), intent(in) :: tol_correction_norm, tol_max_correction
     372              : 
     373              :          integer :: ierr, nz, n
     374              :          logical :: report
     375              : 
     376              :          include 'formats'
     377              : 
     378           11 :          if (s% dt <= 0d0) then
     379           11 :             do_solver_converge = keep_going
     380              :             return
     381              :          end if
     382              : 
     383           11 :          do_solver_converge = terminate
     384              : 
     385           11 :          ierr = 0
     386              : 
     387           11 :          nz = s% nz
     388           11 :          n = nz*nvar
     389              : 
     390           11 :          s% solver_call_number = s% solver_call_number + 1
     391              : 
     392              :          do_solver_converge = do_solver( &
     393              :             s, skip_global_corr_coeff_limit, &
     394              :             tol_correction_norm, tol_max_correction, &
     395           11 :             report, nz, nvar)
     396              : 
     397              : 
     398           11 :       end function do_solver_converge
     399              : 
     400              : 
     401           11 :       subroutine set_surf_info(s, nvar)  ! set to values at start of step
     402              :          type (star_info), pointer :: s
     403              :          integer, intent(in) :: nvar
     404           11 :          s% surf_lnS = s% lnS(1)
     405           11 :          s% num_surf_revisions = 0
     406           11 :       end subroutine set_surf_info
     407              : 
     408              : 
     409           11 :       subroutine set_xh(s,nvar,ierr)  ! set xh using current structure info
     410              :          use hydro_rsp2, only: RSP2_adjust_vars_before_call_solver
     411              :          type (star_info), pointer :: s
     412              :          integer, intent(in) :: nvar
     413              :          integer, intent(out) :: ierr
     414              :          integer :: j1, k, nz
     415              :          include 'formats'
     416           11 :          ierr = 0
     417           11 :          nz = s%nz
     418           11 :          if (s% RSP2_flag) then
     419            0 :             call RSP2_adjust_vars_before_call_solver(s, ierr)
     420            0 :             if (ierr /= 0) then
     421            0 :                if (s% report_ierr) write(*,*) 'failed in RSP2_adjust_vars_before_call_solver'
     422              :                return
     423              :             end if
     424              :          end if
     425           55 :          do j1 = 1, min(nvar,s% nvar_hydro)
     426           55 :             if (j1 == s% i_lnd .and. s% i_lnd <= nvar) then
     427        13098 :                do k = 1, nz
     428        13098 :                   s% xh(j1,k) = s% lnd(k)
     429              :                end do
     430           33 :             else if (j1 == s% i_lnT .and. s% i_lnT <= nvar) then
     431        13098 :                do k = 1, nz
     432        13098 :                   s% xh(j1,k) = s% lnT(k)
     433              :                end do
     434           22 :             else if (j1 == s% i_lnR .and. s% i_lnR <= nvar) then
     435        13098 :                do k = 1, nz
     436        13098 :                   s% xh(j1,k) = s% lnR(k)
     437              :                end do
     438           11 :             else if (j1 == s% i_lum .and. s% i_lum <= nvar) then
     439        13098 :                do k = 1, nz
     440        13098 :                   s% xh(j1,k) = s% L(k)
     441              :                end do
     442            0 :             else if (j1 == s% i_w .and. s% i_w <= nvar) then
     443            0 :                do k = 1, nz
     444            0 :                   s% xh(j1,k) = s% w(k)
     445              :                end do
     446            0 :             else if (j1 == s% i_Hp .and. s% i_Hp <= nvar) then
     447            0 :                do k = 1, nz
     448            0 :                   s% xh(j1,k) = s% Hp_face(k)
     449              :                end do
     450            0 :             else if (j1 == s% i_v .and. s% i_v <= nvar) then
     451            0 :                do k = 1, nz
     452            0 :                   s% xh(j1,k) = s% v(k)
     453              :                end do
     454            0 :             else if (j1 == s% i_u .and. s% i_u <= nvar) then
     455            0 :                do k = 1, nz
     456            0 :                   s% xh(j1,k) = s% u(k)
     457              :                end do
     458            0 :             else if (j1 == s% i_alpha_RTI .and. s% i_alpha_RTI <= nvar) then
     459            0 :                do k = 1, nz
     460            0 :                   s% xh(j1,k) = s% alpha_RTI(k)
     461              :                end do
     462              :             end if
     463              :          end do
     464           11 :       end subroutine set_xh
     465              : 
     466              : 
     467           11 :       subroutine set_tol_correction( &
     468              :             s, T_max, tol_correction_norm, tol_max_correction)
     469              :          type (star_info), pointer :: s
     470              :          real(dp), intent(in) :: T_max
     471              :          real(dp), intent(out) :: tol_correction_norm, tol_max_correction
     472              :          include 'formats'
     473           11 :          if (T_max >= s% tol_correction_extreme_T_limit) then
     474            0 :             tol_correction_norm = s% tol_correction_norm_extreme_T
     475            0 :             tol_max_correction = s% tol_max_correction_extreme_T
     476           11 :          else if (T_max >= s% tol_correction_high_T_limit) then
     477            0 :             tol_correction_norm = s% tol_correction_norm_high_T
     478            0 :             tol_max_correction = s% tol_max_correction_high_T
     479              :          else
     480           11 :             tol_correction_norm = s% tol_correction_norm
     481           11 :             tol_max_correction = s% tol_max_correction
     482              :          end if
     483           11 :       end subroutine set_tol_correction
     484              : 
     485              : 
     486           11 :       integer function do_solver( &
     487              :             s, skip_global_corr_coeff_limit, &
     488              :             tol_correction_norm, tol_max_correction, &
     489              :             report, nz, nvar)
     490              :          ! return keep_going, retry, or terminate
     491              : 
     492              :          ! when using solver for hydro step,
     493              :          ! do not require that functions have been evaluated for starting configuration.
     494              :          ! when finish, will have functions evaluated for the final set of primary variables.
     495              :          ! for example, the reaction rates will have been computed, so they can be used
     496              :          ! as initial values in the following burn and mix.
     497              : 
     498              :          use num_def
     499              :          use alloc
     500              : 
     501              :          type (star_info), pointer :: s
     502              :          integer, intent(in) :: nz, nvar
     503              :          logical, intent(in) :: skip_global_corr_coeff_limit, report
     504              :          real(dp), intent(in) :: tol_correction_norm, tol_max_correction
     505              : 
     506              :          logical :: converged
     507              :          integer :: k, species, ierr, j1, j2, gold_tolerances_level
     508           11 :          real(dp) :: maxT
     509              : 
     510              :          include 'formats'
     511              : 
     512           11 :          species = s% species
     513           11 :          do_solver = keep_going
     514           11 :          s% using_gold_tolerances = .false.
     515           11 :          gold_tolerances_level = 0
     516              : 
     517           11 :          if ((s% use_gold2_tolerances .and. s% steps_before_use_gold2_tolerances < 0) .or. &
     518              :              (s% steps_before_use_gold2_tolerances >= 0 .and. &
     519              :                 s% model_number > s% steps_before_use_gold2_tolerances + max(0,s% init_model_number))) then
     520            0 :             s% using_gold_tolerances = .true.
     521            0 :             gold_tolerances_level = 2
     522           11 :          else if ((s% use_gold_tolerances .and. s% steps_before_use_gold_tolerances < 0) .or. &
     523              :              (s% steps_before_use_gold_tolerances >= 0 .and. &
     524              :                 s% model_number > s% steps_before_use_gold_tolerances + max(0,s% init_model_number))) then
     525           11 :             if (s% maxT_for_gold_tolerances > 0) then
     526        13109 :                maxT = maxval(s% T(1:nz))
     527              :             else
     528              :                maxT = -1d0
     529              :             end if
     530           11 :             if (maxT > s% maxT_for_gold_tolerances) then
     531              :                !write(*,2) 'exceed maxT_for_gold_tolerances', &
     532              :                !   s% model_number, maxT, s% maxT_for_gold_tolerances
     533              :             else  ! okay for maxT, so check if also ok for eosPC_frac
     534           11 :                s% using_gold_tolerances = .true.
     535           11 :                gold_tolerances_level = 1
     536              :             end if
     537              :          end if
     538              : 
     539           11 :          call set_xh(s, nvar, ierr)  ! set xh using current structure info
     540           11 :          if (ierr /= 0) then
     541            0 :             if (report) then
     542            0 :                write(*, *) 'set_xh returned ierr in struct_burn_mix', ierr
     543            0 :                write(*, *) 's% model_number', s% model_number
     544            0 :                write(*, *) 'nz', nz
     545            0 :                write(*, *) 's% num_retries', s% num_retries
     546            0 :                write(*, *)
     547              :             end if
     548            0 :             do_solver = retry
     549            0 :             s% result_reason = nonzero_ierr
     550              :             s% dt_why_retry_count(Tlim_solver) = &
     551            0 :                s% dt_why_retry_count(Tlim_solver) + 1
     552            0 :             return
     553              :          end if
     554              : 
     555        13098 :          do k = 1, nz
     556        65446 :             do j1 = 1, min(nvar, s% nvar_hydro)
     557        65435 :                s% solver_dx(j1,k) = s% xh(j1,k) - s% xh_start(j1,k)
     558              :             end do
     559              :          end do
     560              : 
     561           11 :          if (nvar >= s% nvar_hydro+1) then
     562        13098 :             do k = 1, nz
     563        13087 :                j2 = 1
     564       117794 :                do j1 = s% nvar_hydro+1, nvar
     565       104696 :                   s% xa_sub_xa_start(j2,k) = s% xa(j2,k) - s% xa_start(j2,k)
     566       104696 :                   s% solver_dx(j1,k) = s% xa_sub_xa_start(j2,k)
     567       117783 :                   j2 = j2+1
     568              :                end do
     569              :             end do
     570              :          end if
     571              : 
     572              :          converged = .false.
     573              :          call hydro_solver_step( &
     574              :             s, nz, s% nvar_hydro, nvar, skip_global_corr_coeff_limit, &
     575              :             gold_tolerances_level, tol_max_correction, tol_correction_norm, &
     576           11 :             converged, ierr)
     577           11 :          if (ierr /= 0) then
     578            0 :             if (report) then
     579            0 :                write(*, *) 'hydro_solver_step returned ierr', ierr
     580            0 :                write(*, *) 's% model_number', s% model_number
     581            0 :                write(*, *) 'nz', nz
     582            0 :                write(*, *) 's% num_retries', s% num_retries
     583            0 :                write(*, *)
     584              :             end if
     585            0 :             do_solver = retry
     586            0 :             s% result_reason = nonzero_ierr
     587              :             s% dt_why_retry_count(Tlim_solver) = &
     588            0 :                s% dt_why_retry_count(Tlim_solver) + 1
     589            0 :             return
     590              :          end if
     591              : 
     592           11 :          if (converged) then  ! sanity checks before accept it
     593           11 :             converged = check_after_converge(s, report, ierr)
     594           11 :             if (converged .and. s% RTI_flag) &  ! special checks
     595            0 :                converged = RTI_check_after_converge(s, report, ierr)
     596              :          end if
     597              : 
     598           11 :          if (.not. converged) then
     599            0 :             do_solver = retry
     600            0 :             s% result_reason = hydro_failed_to_converge
     601              :             s% dt_why_retry_count(Tlim_solver) = &
     602            0 :                s% dt_why_retry_count(Tlim_solver) + 1
     603            0 :             if (report) then
     604            0 :                write(*,2) 'solver rejected trial model'
     605            0 :                write(*,2) 's% model_number', s% model_number
     606            0 :                write(*,2) 's% solver_call_number', s% solver_call_number
     607            0 :                write(*,2) 'nz', nz
     608            0 :                write(*,2) 's% num_retries', s% num_retries
     609            0 :                write(*,1) 'dt', s% dt
     610            0 :                write(*,1) 'log dt/secyer', log10(s% dt/secyer)
     611            0 :                write(*, *)
     612              :             end if
     613            0 :             return
     614              :          end if
     615              : 
     616           11 :       end function do_solver
     617              : 
     618              : 
     619            0 :       logical function RTI_check_after_converge(s, report, ierr) result(converged)
     620           11 :          use mesh_adjust, only: set_lnT_for_energy
     621              :          use micro, only: do_eos_for_cell
     622              :          use chem_def, only: ih1, ihe3, ihe4
     623              :          use star_utils, only: store_lnT_in_xh, get_T_and_lnT_from_xh
     624              :          type (star_info), pointer :: s
     625              :          logical, intent(in) :: report
     626              :          integer, intent(out) :: ierr
     627              :          integer :: k, nz
     628            0 :          real(dp) :: old_energy, old_IE, new_IE, old_KE, new_KE, new_u, new_v, &
     629            0 :             revised_energy, new_lnT
     630              :          include 'formats'
     631            0 :          ierr = 0
     632            0 :          nz = s% nz
     633            0 :          converged = .true.
     634              :          !return
     635            0 :          do k=1,nz
     636            0 :             if (k < nz .and. s% alpha_RTI(k) < 1d-10) cycle
     637            0 :             old_energy = s% energy(k)
     638            0 :             old_IE = old_energy*s% dm(k)
     639            0 :             if (s% energy(k) < s% RTI_energy_floor) then
     640              :                ! try to take from KE to give to IE
     641              :                ! else just bump energy and take hit to energy conservation
     642            0 :                s% energy(k) = s% RTI_energy_floor
     643            0 :                s% lnE(k) = log(s% energy(k))
     644              :                call set_lnT_for_energy(s, k, &
     645              :                   s% net_iso(ih1), s% net_iso(ihe3), s% net_iso(ihe4), &
     646              :                   s% species, s% xa(:,k), &
     647              :                   s% rho(k), s% lnd(k)/ln10, s% energy(k), s% lnT(k), &
     648            0 :                   new_lnT, revised_energy, ierr)
     649            0 :                if (ierr /= 0) return  ! call mesa_error(__FILE__,__LINE__,'do_merge failed in set_lnT_for_energy')
     650            0 :                call store_lnT_in_xh(s, k, new_lnT)
     651            0 :                call get_T_and_lnT_from_xh(s, k, s% T(k), s% lnT(k))
     652              :             end if
     653            0 :             new_IE = s% energy(k)*s% dm(k)
     654            0 :             if (s% u_flag) then
     655            0 :                old_KE = 0.5d0*s% dm(k)*s% u(k)*s% u(k)
     656            0 :                new_KE = max(0d0, old_KE + old_IE - new_IE)
     657            0 :                new_u = sqrt(new_KE/(0.5d0*s% dm(k)))
     658            0 :                if (s% u(k) > 0d0) then
     659            0 :                   s% u(k) = new_u
     660              :                else
     661            0 :                   s% u(k) = -new_u
     662              :                end if
     663            0 :                s% xh(s% i_u, k) = s% u(k)
     664            0 :             else if (s% v_flag) then  ! only rough approximation possible here
     665            0 :                old_KE = 0.5d0*s% dm_bar(k)*s% v(k)*s% v(k)
     666            0 :                new_KE = max(0d0, old_KE + old_IE - new_IE)
     667            0 :                new_v = sqrt(max(0d0,new_KE)/(0.5d0*s% dm_bar(k)))
     668            0 :                if (s% v(k) > 0d0) then
     669            0 :                   s% v(k) = new_v
     670              :                else
     671            0 :                   s% v(k) = -new_v
     672              :                end if
     673            0 :                s% xh(s% i_v, k) = s% v(k)
     674              :             end if
     675              :          end do
     676            0 :       end function RTI_check_after_converge
     677              : 
     678              : 
     679           11 :       logical function check_after_converge(s, report, ierr) result(converged)
     680              :          type (star_info), pointer :: s
     681              :          logical, intent(in) :: report
     682              :          integer, intent(out) :: ierr
     683              :          integer :: k, nz
     684              :          include 'formats'
     685           11 :          ierr = 0
     686           11 :          nz = s% nz
     687           11 :          converged = .true.
     688           11 :          if (s% R_center > 0) then
     689            0 :             if (s% R_center > exp(s% lnR(nz))) then
     690            0 :                if (report) &
     691            0 :                   write(*,2) 'volume < 0 in cell nz', nz, &
     692            0 :                      s% R_center - exp(s% lnR(nz)), s% R_center, exp(s% lnR(nz)), &
     693            0 :                      s% dm(nz), s% rho(nz), s% dq(nz)
     694            0 :                converged = .false.
     695            0 :                return
     696              :             end if
     697              :          end if
     698        13087 :          do k=1,nz-1
     699        13087 :             if (s% lnR(k) <= s% lnR(k+1)) then
     700            0 :                if (report) write(*,2) 'after hydro, negative cell volume in cell k', &
     701            0 :                      k, s% lnR(k) - s% lnR(k+1), s% lnR(k), s% lnR(k+1), &
     702            0 :                      s% lnR_start(k) - s% lnR_start(k+1), s% lnR_start(k), s% lnR_start(k+1)
     703              :                converged = .false.; exit
     704              :                call mesa_error(__FILE__,__LINE__,'check_after_converge')
     705              :             else
     706        13076 :                if (s% lnT(k) > ln10*12) then
     707            0 :                   if (report) write(*,2) 'after hydro, logT > 12 in cell k', k, s% lnT(k)
     708              :                   converged = .false.  !; exit
     709        13076 :                else if (s% lnT(k) < ln10) then
     710            0 :                   if (report) write(*,*) 'after hydro, logT < 1 in cell k', k
     711              :                   converged = .false.  !; exit
     712        13076 :                else if (s% lnd(k) > ln10*12) then
     713            0 :                   if (report) write(*,*) 'after hydro, logRho > 12 in cell k', k
     714              :                   converged = .false.  !; exit
     715        13076 :                else if (s% lnd(k) < -ln10*30) then
     716            0 :                   if (report) write(*,*) 'after hydro, logRho < -30 in cell k', k
     717              :                   converged = .false.  !; exit
     718              :                end if
     719              :             end if
     720              :          end do
     721            0 :       end function check_after_converge
     722              : 
     723              : 
     724           11 :       subroutine hydro_solver_step( &
     725              :             s, nz, nvar_hydro, nvar, skip_global_corr_coeff_limit, &
     726              :             gold_tolerances_level, tol_max_correction, tol_correction_norm, &
     727              :             converged, ierr)
     728              :          use num_def
     729              :          use chem_def
     730              :          use mtx_lib
     731              :          use mtx_def
     732              :          use alloc
     733              : 
     734              :          type (star_info), pointer :: s
     735              :          integer, intent(in) :: nz, nvar_hydro, nvar
     736              :          logical, intent(in) :: skip_global_corr_coeff_limit
     737              :          real(dp), intent(in) :: tol_max_correction, tol_correction_norm
     738              :          integer, intent(in) :: gold_tolerances_level
     739              :          logical, intent(out) :: converged
     740              :          integer, intent(out) :: ierr
     741              : 
     742              :          integer :: k, j, neq
     743              :          logical :: failure
     744              :          logical, parameter :: dbg = .false.
     745              : 
     746              :          include 'formats'
     747              : 
     748              :          ierr = 0
     749              : 
     750           11 :          neq = nvar*nz
     751              : 
     752              :          if (dbg) write(*, *) 'enter hydro_solver_step'
     753              : 
     754           11 :          s% used_extra_iter_in_solver_for_accretion = .false.
     755              : 
     756           11 :          call check_sizes(s, ierr)
     757           11 :          if (ierr /= 0) then
     758            0 :             write(*,*) 'check_sizes failed'
     759              :             return
     760              :          end if
     761              : 
     762              :          if (dbg) write(*, *) 'call solver'
     763           11 :          call newt(ierr)
     764           11 :          if (ierr /= 0 .and. s% report_ierr) then
     765            0 :             write(*,*) 'solver failed for hydro'
     766              :          end if
     767              : 
     768           11 :          converged = (ierr == 0) .and. (.not. failure)
     769           22 :          if (converged) then
     770        13098 :             do k=1,nz
     771        65446 :                do j=1,min(nvar,nvar_hydro)
     772        65435 :                   s% xh(j,k) = s% xh_start(j,k) + s% solver_dx(j,k)
     773              :                end do
     774              :             end do
     775              :             ! s% xa has already been updated by final call to set_solver_vars from solver
     776              :          end if
     777              : 
     778              : 
     779              :          contains
     780              : 
     781              : 
     782           11 :          subroutine newt(ierr)
     783           11 :             use star_solver, only: solver
     784              :             use rates_def, only: warn_rates_for_high_temp
     785              :             integer, intent(out) :: ierr
     786              :             logical :: save_warn_rates_flag
     787              :             include 'formats'
     788           11 :             s% doing_solver_iterations = .true.
     789           11 :             save_warn_rates_flag = warn_rates_for_high_temp
     790           11 :             warn_rates_for_high_temp = .false.
     791              :             call solver( &
     792              :                s, nvar, skip_global_corr_coeff_limit, &
     793              :                gold_tolerances_level, tol_max_correction, tol_correction_norm, &
     794           11 :                failure, ierr)
     795           11 :             s% doing_solver_iterations = .false.
     796           11 :             warn_rates_for_high_temp = save_warn_rates_flag
     797           11 :          end subroutine newt
     798              : 
     799              : 
     800              :       end subroutine hydro_solver_step
     801              : 
     802              : 
     803            0 :       integer function do_burn(s, dt)
     804              :          use star_utils, only: start_time, update_time
     805              :          use net, only: get_screening_mode
     806              :          use chem_def
     807              :          use micro, only: do_eos_for_cell
     808              : 
     809              :          type (star_info), pointer :: s
     810              :          real(dp), intent(in) :: dt
     811              : 
     812              :          integer :: &
     813              :             k_bad, ierr, max_num_iters_k, nz, op_err, &
     814              :             k, num_iters, species, max_num_iters_used, &
     815              :             screening_mode, kmin
     816              :          integer(i8) :: time0
     817            0 :          real(dp) :: total, avg_epsnuc, min_T_for_const_density_solver
     818              :          logical :: trace, dbg, skip_burn
     819              :          logical, parameter :: burn_dbg = .false.
     820              : 
     821              :          include 'formats'
     822              : 
     823            0 :          trace = .false.
     824              : 
     825            0 :          min_T_for_const_density_solver = s% op_split_burn_min_T_for_variable_T_solver
     826              : 
     827            0 :          do_burn = keep_going
     828            0 :          ierr = 0
     829            0 :          nz = s% nz
     830            0 :          species = s% species
     831              : 
     832            0 :          if (s% eps_nuc_factor == 0d0 .and. s% dxdt_nuc_factor == 0d0) then
     833            0 :             do k = 1, nz
     834            0 :                s% eps_nuc(k) = 0d0
     835            0 :                s% burn_num_iters(k) = 0
     836            0 :                s% burn_avg_epsnuc(k) = 0d0
     837            0 :                s% max_burn_correction(k) = 0d0
     838              :             end do
     839              :             return
     840              :          end if
     841              : 
     842            0 :          if (dt <= 0d0) return
     843              : 
     844            0 :          max_num_iters_used = 0
     845            0 :          max_num_iters_k = 0
     846            0 :          k_bad = 0
     847              : 
     848            0 :          screening_mode = get_screening_mode(s,ierr)
     849            0 :          if (ierr /= 0) then
     850            0 :             if (s% report_ierr) &
     851            0 :                write(*,*) 'unknown string for screening_mode: ' // trim(s% screening_mode)
     852            0 :             return
     853              :             call mesa_error(__FILE__,__LINE__,'do1_net')
     854              :          end if
     855              : 
     856            0 :          dbg = .false.  ! (s% model_number == 1137)
     857              : 
     858            0 :          kmin = nz+1
     859            0 :          do k=1,nz
     860            0 :             if (s% T_start(k) < s% op_split_burn_min_T) then
     861              :                 ! We get here if we have an off center ignition,
     862              :                 ! the arrays wont have been initialised earlier as they stop at the
     863              :                 ! first temperature that exceeds op_split_burn_min_T
     864            0 :                s% burn_num_iters(k) = 0
     865            0 :                s% burn_avg_epsnuc(k) = 0d0
     866              :                cycle
     867              :             end if
     868              :             kmin = k
     869            0 :             exit
     870              :          end do
     871              : 
     872            0 :          if (kmin > nz) return
     873              : 
     874              :          !skip_burn = s% fe_core_infall > s% op_split_burn_eps_nuc_infall_limit
     875            0 :          skip_burn = (minval(s% v_start(1:s% nz)) < -s% op_split_burn_eps_nuc_infall_limit)
     876              : 
     877            0 :          if (s% doing_timing) call start_time(s, time0, total)
     878              : 
     879            0 : !$OMP PARALLEL DO PRIVATE(k,op_err,num_iters,avg_epsnuc) SCHEDULE(dynamic,2)
     880              :          do k = kmin, nz
     881              :             if (k_bad /= 0) cycle
     882              :             if (s% T_start(k) < s% op_split_burn_min_T) then
     883              :                ! We get here if we have an off center ignition,
     884              :                ! the arrays wont have been initialised earlier as they stop at the
     885              :                ! first temperature that exceeds op_split_burn_min_T
     886              :                s% burn_num_iters(k) = 0
     887              :                s% burn_avg_epsnuc(k) = 0d0
     888              :                cycle
     889              :             end if
     890              :             s% max_burn_correction(k) = 0d0
     891              :             op_err = 0
     892              :             call burn1_zone( &
     893              :                s, k, species, min_T_for_const_density_solver, skip_burn, &
     894              :                screening_mode, &
     895              :                dt, num_iters, avg_epsnuc, burn_dbg, op_err)
     896              :             if (op_err /= 0) then
     897              :                ierr = -1
     898              :                k_bad = k
     899              :                cycle
     900              :             end if
     901              :             call do_eos_for_cell(s,k,op_err)
     902              :             if (op_err /= 0) then
     903              :                write(*,2) 'do_burn failed in do_eos_for_cell', k
     904              :                ierr = -1
     905              :                k_bad = k
     906              :                cycle
     907              :             end if
     908              :             !write(*,3) 'num_iters', k, num_iters
     909              :             s% burn_num_iters(k) = num_iters
     910              :             s% burn_avg_epsnuc(k) = avg_epsnuc
     911              :             if (num_iters > max_num_iters_used) then
     912              :                max_num_iters_used = num_iters
     913              :                max_num_iters_k = k
     914              :             end if
     915              :          end do
     916              : !$OMP END PARALLEL DO
     917              : 
     918            0 :          s% need_to_setvars = .true.
     919              : 
     920            0 :          if (s% doing_timing) &
     921            0 :             call update_time(s, time0, total, s% time_solve_burn)
     922              : 
     923            0 :          if (ierr /= 0) then
     924            0 :             if (s% report_ierr) write(*,2) 'do_burn failed', k_bad
     925            0 :             return
     926              :             call mesa_error(__FILE__,__LINE__,'do_burn')
     927              : 
     928              : 
     929              :             do_burn = retry
     930              :             if (trace .or. s% report_ierr) then
     931              :                write(*,*) 'do_burn ierr'
     932              :             end if
     933              :             call restore
     934              :             return
     935              :          end if
     936              : 
     937            0 :          if (dbg) write(*,2) 'done do_burn'
     938              : 
     939              : 
     940              :          contains
     941              : 
     942              :          subroutine restore
     943              :             integer :: j, k
     944              :             do k = 1, nz
     945              :                do j=1,species
     946              :                   s% xa(j,k) = s% xa_start(j,k)
     947              :                end do
     948              :             end do
     949            0 :          end subroutine restore
     950              : 
     951              :       end function do_burn
     952              : 
     953              : 
     954            0 :       subroutine burn1_zone( &
     955              :             s, k, species, min_T_for_const_density_solver, skip_burn, &
     956              :             screening_mode, &
     957              :             dt, num_iters_out, avg_epsnuc, dbg_in, ierr)
     958              :          use net_lib, only: net_1_zone_burn_const_density, net_1_zone_burn, &
     959              :             show_net_reactions_and_info
     960              :          use rates_def, only: std_reaction_Qs, std_reaction_neuQs
     961              :          use chem_def, only: num_categories
     962              :          use net, only: do1_net
     963              :          use star_utils, only: store_lnT_in_xh, get_T_and_lnT_from_xh
     964              :          type (star_info), pointer :: s
     965              :          integer, intent(in) :: k, species,  screening_mode
     966              :          real(dp), intent(in) :: dt, min_T_for_const_density_solver
     967              :          logical, intent(in) :: skip_burn, dbg_in
     968              :          real(dp), intent(out) :: avg_epsnuc
     969              :          integer, intent(out) :: num_iters_out, ierr
     970              : 
     971            0 :          real(dp), target :: xa_start_ary(species)
     972            0 :          real(dp), pointer :: xa_start(:)
     973              : 
     974            0 :          real(dp) :: stptry, eps, odescal, &
     975            0 :             starting_log10T, ending_log10T, ending_eps_neu_total, &
     976            0 :             Cv0, eta0, substep_start_time
     977              :          integer :: i, max_steps, nfcn, njac, ntry, naccpt, nrejct
     978              :          integer, parameter :: num_times = 1
     979            0 :          real(dp), target, dimension(4*num_times) :: log10Ts_ary, log10Rhos_ary, etas_ary
     980            0 :          real(dp), pointer, dimension(:) :: log10Ts_f1, log10Rhos_f1, etas_f1, &
     981            0 :             dxdt_source_term, times
     982              :          logical :: use_pivoting, trace, burn_dbg
     983              : 
     984              :          include 'formats'
     985              : 
     986            0 :          ierr = 0
     987            0 :          num_iters_out = 0
     988              : 
     989            0 :          if (skip_burn) then
     990            0 :             avg_epsnuc = 0d0
     991            0 :             s% eps_nuc(k) = 0d0
     992            0 :             s% d_epsnuc_dlnd(k) = 0d0
     993            0 :             s% d_epsnuc_dlnT(k) = 0d0
     994            0 :             s% d_epsnuc_dx(:,k) = 0d0
     995            0 :             s% dxdt_nuc(:,k) = 0d0
     996            0 :             s% eps_nuc_categories(:,k) = 0d0
     997            0 :             s% d_dxdt_nuc_dRho(:,k) =  0d0
     998            0 :             s% d_dxdt_nuc_dT(:,k) =  0d0
     999            0 :             s% d_dxdt_nuc_dx(:,:,k) =  0d0
    1000            0 :             s% eps_nuc_neu_total(k) = 0d0
    1001            0 :             return
    1002              :          end if
    1003              : 
    1004            0 :          log10Ts_f1 => log10Ts_ary
    1005            0 :          log10Rhos_f1 => log10Rhos_ary
    1006            0 :          etas_f1 => etas_ary
    1007              : 
    1008            0 :          nullify(dxdt_source_term, times)
    1009              : 
    1010            0 :          xa_start => xa_start_ary
    1011              : 
    1012            0 :          stptry = 0d0
    1013            0 :          eps = s% op_split_burn_eps
    1014            0 :          odescal = s% op_split_burn_odescal
    1015            0 :          max_steps = s% burn_steps_hard_limit
    1016            0 :          use_pivoting = .false.  ! .true.
    1017            0 :          trace = .false.
    1018            0 :          burn_dbg = .false.
    1019            0 :          starting_log10T = s% lnT(k)/ln10
    1020              : 
    1021            0 :          do i=1,species
    1022            0 :             xa_start(i) = s% xa(i,k)
    1023              :          end do
    1024              : 
    1025            0 :          substep_start_time = 0d0
    1026              : 
    1027            0 :          if (s% use_other_split_burn) then
    1028            0 :             log10Ts_f1 => log10Ts_ary
    1029            0 :             log10Rhos_f1 => log10Rhos_ary
    1030            0 :             etas_f1 => etas_ary
    1031              :             nullify(dxdt_source_term, times)
    1032            0 :             log10Ts_f1(1) = s% lnT(k)/ln10
    1033            0 :             log10Rhos_f1(1) = s% lnd(k)/ln10
    1034            0 :             etas_f1(1) = s% eta(k)
    1035              :             call s% other_split_burn( &
    1036              :                s%id, k, s% net_handle, s% eos_handle, species, s% num_reactions, 0d0, dt, xa_start, &
    1037              :                num_times, times, log10Ts_f1, log10Rhos_f1, etas_f1, dxdt_source_term, &
    1038              :                s% rate_factors, s% weak_rate_factor, &
    1039              :                std_reaction_Qs, std_reaction_neuQs, &
    1040              :                screening_mode,  &
    1041              :                stptry, max_steps, eps, odescal, &
    1042              :                use_pivoting, trace, burn_dbg, burn_finish_substep, &
    1043              :                s% xa(1:species,k), &
    1044              :                s% eps_nuc_categories(:,k), &
    1045              :                avg_epsnuc, ending_eps_neu_total, &
    1046            0 :                nfcn, njac, ntry, naccpt, nrejct, ierr)
    1047            0 :             if (ierr /= 0) then
    1048            0 :                if (s% report_ierr) write(*,2) 'other_split_burn failed', k
    1049            0 :                return
    1050              :                call mesa_error(__FILE__,__LINE__,'burn1_zone')
    1051              :             end if
    1052              : 
    1053            0 :          else if (s% T(k) >= min_T_for_const_density_solver) then
    1054            0 :             Cv0 = s% Cv(k)
    1055            0 :             eta0 = s% eta(k)
    1056              :             call net_1_zone_burn_const_density( &
    1057              :                s% net_handle, s% eos_handle, species, s% num_reactions, 0d0, dt, &
    1058              :                xa_start, starting_log10T, s% lnd(k)/ln10, &
    1059              :                get_eos_info_for_burn_at_const_density, &
    1060              :                s% rate_factors, s% weak_rate_factor, &
    1061              :                std_reaction_Qs, std_reaction_neuQs, &
    1062              :                screening_mode, &
    1063              :                stptry, max_steps, eps, odescal, &
    1064              :                use_pivoting, trace, burn_dbg, burn_finish_substep, &
    1065              :                s% xa(1:species,k), &
    1066              :                s% eps_nuc_categories(:,k), &
    1067              :                ending_log10T, avg_epsnuc, ending_eps_neu_total, &
    1068            0 :                nfcn, njac, ntry, naccpt, nrejct, ierr)
    1069            0 :             if (ierr /= 0) then
    1070            0 :                if (s% report_ierr) write(*,2) 'net_1_zone_burn_const_density failed', k
    1071            0 :                return
    1072              :                call mesa_error(__FILE__,__LINE__,'burn1_zone')
    1073              :             end if
    1074              :             ! restore temperature
    1075            0 :             call store_lnT_in_xh(s, k, starting_log10T*ln10)
    1076            0 :             call get_T_and_lnT_from_xh(s, k, s% T(k), s% lnT(k))
    1077              :          else
    1078            0 :             log10Ts_f1 => log10Ts_ary
    1079            0 :             log10Rhos_f1 => log10Rhos_ary
    1080            0 :             etas_f1 => etas_ary
    1081              :             nullify(dxdt_source_term, times)
    1082            0 :             log10Ts_f1(1) = s% lnT(k)/ln10
    1083            0 :             log10Rhos_f1(1) = s% lnd(k)/ln10
    1084            0 :             etas_f1(1) = s% eta(k)
    1085              :             call net_1_zone_burn( &
    1086              :                s% net_handle, s% eos_handle, species, s% num_reactions, 0d0, dt, xa_start, &
    1087              :                num_times, times, log10Ts_f1, log10Rhos_f1, etas_f1, dxdt_source_term, &
    1088              :                s% rate_factors, s% weak_rate_factor, &
    1089              :                std_reaction_Qs, std_reaction_neuQs, &
    1090              :                screening_mode,  &
    1091              :                stptry, max_steps, eps, odescal, &
    1092              :                use_pivoting, trace, burn_dbg, burn_finish_substep, &
    1093              :                s% xa(1:species,k), &
    1094              :                s% eps_nuc_categories(:,k), &
    1095              :                avg_epsnuc, ending_eps_neu_total, &
    1096            0 :                nfcn, njac, ntry, naccpt, nrejct, ierr)
    1097            0 :             if (ierr /= 0) then
    1098            0 :                if (s% report_ierr) write(*,2) 'net_1_zone_burn failed', k
    1099            0 :                return
    1100              :                call mesa_error(__FILE__,__LINE__,'burn1_zone')
    1101              :             end if
    1102              :          end if
    1103              : 
    1104            0 :          s% raw_rate(:,k) = 0d0
    1105            0 :          s% screened_rate(:,k) = 0d0
    1106            0 :          s% eps_nuc_rate(:,k) = 0d0
    1107            0 :          s% eps_neu_rate(:,k) = 0d0
    1108              : 
    1109            0 :          num_iters_out = naccpt
    1110              : 
    1111              :          ! make extra call to get eps_nuc_categories
    1112            0 :          call do1_net(s, k, s% species, s% num_reactions, .false., ierr)
    1113            0 :          if (ierr /= 0) then
    1114            0 :             if (s% report_ierr) &
    1115            0 :                write(*,2) 'net_1_zone_burn final call to do1_net failed', k
    1116            0 :             return
    1117              :             call mesa_error(__FILE__,__LINE__,'burn1_zone')
    1118              :          end if
    1119              : 
    1120            0 :          s% eps_nuc(k) = 0d0
    1121            0 :          s% d_epsnuc_dlnd(k) = 0d0
    1122            0 :          s% d_epsnuc_dlnT(k) = 0d0
    1123            0 :          s% d_epsnuc_dx(:,k) = 0d0
    1124            0 :          s% dxdt_nuc(:,k) = 0d0
    1125              :          !s% eps_nuc_categories(:,k) = 0d0
    1126            0 :          s% d_dxdt_nuc_dRho(:,k) =  0d0
    1127            0 :          s% d_dxdt_nuc_dT(:,k) =  0d0
    1128            0 :          s% d_dxdt_nuc_dx(:,:,k) =  0d0
    1129              :          ! below, restore eps_nuc_neu to op_split zones.
    1130            0 :          s% eps_nuc_neu_total(k) = ending_eps_neu_total
    1131              : 
    1132            0 :          do i=1,species  ! for use by dX_nuc_drop timestep limiter
    1133            0 :             s% dxdt_nuc(i,k) = (s% xa(i,k)-xa_start(i))/dt
    1134              :          end do
    1135              : 
    1136              :          contains
    1137              : 
    1138            0 :          subroutine get_eos_info_for_burn_at_const_density( &
    1139            0 :                eos_handle, species, chem_id, net_iso, xa, &
    1140              :                Rho, logRho, T, logT, &
    1141              :                Cv, d_Cv_dlnT, eta, d_eta_dlnT, ierr)
    1142            0 :             use eos_lib, only: eosDT_get
    1143              :             use eos_def
    1144              :             integer, intent(in) :: eos_handle, species
    1145              :             integer, pointer :: chem_id(:)  ! maps species to chem id
    1146              :             integer, pointer :: net_iso(:)  ! maps chem id to species number
    1147              :             real(dp), intent(in) :: &
    1148              :                xa(:), rho, logRho, T, logT
    1149              :             real(dp), intent(out) :: &
    1150              :                Cv, d_Cv_dlnT, eta, d_eta_dlnT
    1151              :             integer, intent(out) :: ierr
    1152              : 
    1153            0 :             real(dp), dimension(num_eos_basic_results) :: res, d_dlnd, d_dlnT
    1154            0 :             real(dp) :: d_dxa(num_eos_d_dxa_results,species)
    1155              : 
    1156              :             include 'formats'
    1157              :             ierr = 0
    1158              : 
    1159              :             call eosDT_get( &
    1160              :                eos_handle, species, chem_id, net_iso, xa, &
    1161              :                Rho, logRho, T, logT, &
    1162            0 :                res, d_dlnd, d_dlnT, d_dxa, ierr)
    1163              : 
    1164            0 :             if (ierr /= 0) then
    1165            0 :                write(*,*) 'failed in eosDT_get'
    1166              :                return
    1167              :             end if
    1168              : 
    1169            0 :             Cv = res(i_cv)
    1170            0 :             d_Cv_dlnT = d_dlnT(i_cv)
    1171              : 
    1172            0 :             eta = res(i_eta)
    1173            0 :             d_eta_dlnT = d_dlnT(i_eta)
    1174              : 
    1175            0 :          end subroutine get_eos_info_for_burn_at_const_density
    1176              : 
    1177              : 
    1178            0 :          subroutine burn_finish_substep(nstp, time, y, ierr)
    1179              :             integer,intent(in) :: nstp
    1180              :             real(dp), intent(in) :: time, y(:)
    1181              :             integer, intent(out) :: ierr
    1182              :             !real(dp) :: frac, step_time
    1183              :             !integer :: j, i
    1184              :             include 'formats'
    1185            0 :             ierr = 0
    1186              :             ! This routine does nothing other than set ierr = 0,
    1187              :             ! but we need an empty routine here because
    1188              :             ! net_1_zone_burn_const_density
    1189              :             ! expects to be passed a routine burn_finish_substep,
    1190              :             ! and often that will be a routine that actually does something,
    1191              :             ! but here we don't want to do anything.
    1192              : 
    1193              :             !step_time = time - substep_start_time
    1194              :             !if (step_time <= 0d0) return
    1195              :             !frac = step_time/dt
    1196              :             !do j = 1, num_categories
    1197              :             !   s% eps_nuc_categories(j,k) = &
    1198              :             !      s% eps_nuc_categories(j,k) + frac*eps_nuc_cat(j)
    1199              :             !end do
    1200              :             !if (.false. .and. k == s% nz) then
    1201              :             !   i = maxloc(eps_nuc_cat(1:num_categories),dim=1)
    1202              :             !   write(*,3) 'frac time/dt eps_nuc_cat ' // trim(category_name(i)), &
    1203              :             !      i, k, frac, time/dt, eps_nuc_cat(i), s% eps_nuc_categories(i,k)
    1204              :             !end if
    1205              :             !substep_start_time = time
    1206            0 :          end subroutine burn_finish_substep
    1207              : 
    1208              :       end subroutine burn1_zone
    1209              : 
    1210              : 
    1211              :       end module struct_burn_mix
    1212              : 
    1213              : 
        

Generated by: LCOV version 2.0-1