LCOV - code coverage report
Current view: top level - star/private - solver_support.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 46.4 % 728 338
Test Date: 2025-05-08 18:23:42 Functions: 75.0 % 16 12

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2012-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 solver_support
      21              : 
      22              :       use star_private_def
      23              :       use utils_lib, only: is_bad
      24              :       use const_def, only: dp, msun, secyer, ln10, four_thirds_pi
      25              :       use num_def
      26              : 
      27              :       implicit none
      28              : 
      29              :       private
      30              :       public :: force_another_iteration
      31              :       public :: eval_equations
      32              :       public :: set_xscale_info
      33              :       public :: sizequ
      34              :       public :: sizeB
      35              :       public :: inspectb
      36              :       public :: bdomain
      37              : 
      38              :       logical, parameter :: dbg = .false.
      39              : 
      40              :       contains
      41              : 
      42           11 :       subroutine set_xscale_info(s, nvar, ierr)
      43              :          type (star_info), pointer :: s
      44              :          integer, intent(in) :: nvar
      45              :          integer, intent(out) :: ierr
      46              : 
      47              :          integer :: i, k, nz, nvar_hydro
      48              :          real(dp), parameter :: xscale_min = 1
      49              : 
      50              :          include 'formats'
      51              : 
      52           11 :          ierr = 0
      53              : 
      54              :          if (dbg) write(*, *) 'set_xscale'
      55           11 :          nvar_hydro = s% nvar_hydro
      56           11 :          nz = s% nz
      57        13098 :          do k=1,nz
      58       170142 :             do i=1,nvar
      59       170131 :                if (i <= nvar_hydro) then  ! structure variable
      60        52348 :                   if (i == s% i_j_rot) then
      61            0 :                      s% x_scale(i,k) = 10d0*sqrt(s% cgrav(k)*s% m(k)*s% r_start(k))
      62              :                   else
      63        52348 :                      s% x_scale(i,k) = max(xscale_min, abs(s% xh_start(i,k)))
      64              :                   end if
      65              :                else  ! abundance variable
      66       104696 :                   s% x_scale(i,k) = max(s% xa_scale, s% xa_start(i-nvar_hydro,k))
      67              :                end if
      68              :             end do
      69              :          end do
      70              : 
      71              :          contains
      72              : 
      73              :          subroutine dump_xscale
      74              :             integer :: k, j
      75              :             include 'formats'
      76              :             !write(*,1) 's% xa_scale', s% xa_scale
      77              :             do k=1,s% nz
      78              :                do j=1,nvar
      79              :                   write(*,2) 'xscale ' // trim(s% nameofvar(j)), k, s% x_scale(j,k)
      80              :                end do
      81              :                write(*,'(A)')
      82              :             end do
      83              :             call mesa_error(__FILE__,__LINE__,'set_xscale')
      84              :          end subroutine dump_xscale
      85              : 
      86              :       end subroutine set_xscale_info
      87              : 
      88              : 
      89           44 :       subroutine eval_equations(s,  nvar, ierr)
      90              :          use hydro_eqns, only: eval_equ
      91              :          use mix_info, only: set_dxdt_mix
      92              :          use star_utils, only: update_time, total_times
      93              :          type (star_info), pointer :: s
      94              :          integer, intent(in) :: nvar
      95              :          integer, intent(out) :: ierr
      96              : 
      97              :          integer :: cnt, i, j, k, nz
      98              :          real(dp) :: dt
      99              :          include 'formats'
     100              : 
     101           44 :          ierr = 0
     102           44 :          nz = s% nz
     103              : 
     104              :          if (dbg) write(*, *) 'eval_equations'
     105              : 
     106           44 :          dt = s% dt
     107              : 
     108           44 :          if (s% solver_iter == 0) then
     109              :             if (dbg) write(*, *) 'skip set_solver_vars on call before 1st iter'
     110              :          else
     111              :             if (dbg) write(*, *) 'call set_solver_vars'
     112           33 :             call set_solver_vars(s, nvar, dt, ierr)
     113           33 :             if (ierr /= 0) then
     114            0 :                if (s% report_ierr) &
     115            0 :                   write(*,2) 'eval_equations: set_solver_vars returned ierr', ierr
     116            0 :                return
     117              :             end if
     118              :          end if
     119              : 
     120           44 :          call set_dxdt_mix(s)
     121              : 
     122           44 :          if (ierr == 0) then
     123        52392 :             do k=1,nz
     124       680568 :                do j=1,nvar
     125       628176 :                   s% equ(j,k) = 0d0
     126       628176 :                   s% residual_weight(j,k) = 1d0
     127       680524 :                   s% correction_weight(j,k) = 1d0
     128              :                end do
     129              :             end do
     130              :             if (dbg) write(*, *) 'call eval_equ'
     131           44 :             call eval_equ(s, nvar, ierr)
     132           44 :             if (ierr /= 0) then
     133            0 :                if (s% report_ierr) &
     134            0 :                   write(*, *) 'eval_equations: eval_equ returned ierr', ierr
     135            0 :                return
     136              :             end if
     137              :          end if
     138              : 
     139           44 :          if (ierr /= 0) return
     140              : 
     141           44 :          if (.not. s% stop_for_bad_nums) return
     142              : 
     143           44 :          cnt = 0
     144        52392 :          do i=1,nz
     145       680568 :             do j=1, nvar
     146       680524 :                if (is_bad_num(s% equ(j, i))) then
     147            0 :                   cnt = cnt + 1
     148            0 :                   s% retry_message = 'eval_equations: equ has a bad num'
     149            0 :                   if (s% report_ierr) then
     150            0 :                      write(*,4) 'eval_equations: equ has a bad num ' // trim(s% nameofequ(j)), &
     151            0 :                         j, i, nvar, s% equ(j, i)
     152            0 :                      write(*,2) 'cell', i
     153            0 :                      write(*,2) 'nz', s% nz
     154              :                   end if
     155            0 :                   if (s% stop_for_bad_nums) call mesa_error(__FILE__,__LINE__,'eval_equations')
     156              :                end if
     157              :             end do
     158              :          end do
     159              : 
     160           44 :          if (cnt > 0) then
     161            0 :             ierr = -1
     162            0 :             return
     163              :          end if
     164              : 
     165              : 
     166              :          contains
     167              : 
     168              : 
     169              :          subroutine dump_eval_equ
     170              :             integer :: k, j
     171              :             include 'formats'
     172              :             do k=1,s% nz
     173              :                do j=1,nvar
     174              :                   write(*,2) 'dx ' // trim(s% nameofvar(j)), k, s% solver_dx(j, k)
     175              :                end do
     176              :                write(*,'(A)')
     177              :             end do
     178              :             call mesa_error(__FILE__,__LINE__,'dump_eval_equ')
     179           44 :          end subroutine dump_eval_equ
     180              : 
     181              : 
     182              :       end subroutine eval_equations
     183              : 
     184              : 
     185           44 :       subroutine sizequ(s, nvar, equ_norm, equ_max, k_max, j_max, ierr)  ! equ = residuals
     186              :          type (star_info), pointer :: s
     187              :          integer, intent(in) :: nvar
     188              :          real(dp), intent(out) :: equ_norm, equ_max
     189              :          integer, intent(out) :: k_max, j_max, ierr
     190              : 
     191              :          integer :: j, k, num_terms, n, nz, nvar_hydro, nvar_chem, skip_eqn1, skip_eqn2, skip_eqn3
     192           44 :          real(dp) :: sumequ, absq
     193              : 
     194              :          logical :: dbg
     195              : 
     196              :          include 'formats'
     197              : 
     198           44 :          ierr = 0
     199              : 
     200           44 :          equ_norm = 0d0
     201           44 :          equ_max = 0d0
     202           44 :          k_max = 0
     203           44 :          j_max = 0
     204              : 
     205           44 :          dbg = s% solver_check_everything
     206              : 
     207           44 :          nvar_hydro = min(nvar, s% nvar_hydro)
     208           44 :          nvar_chem = s% nvar_chem
     209              : 
     210           44 :          nz = s% nz
     211           44 :          n = nz
     212           44 :          num_terms = 0
     213           44 :          sumequ = 0
     214           44 :          skip_eqn1 = 0
     215           44 :          skip_eqn2 = 0
     216           44 :          skip_eqn3 = 0
     217           44 :          if (s% convergence_ignore_equL_residuals) skip_eqn1 = s% i_equL
     218           44 :          if (s% convergence_ignore_alpha_RTI_residuals) skip_eqn2 = s% i_dalpha_RTI_dt
     219           44 :          if (s% do_burn .or. s% do_mix) then
     220           44 :             num_terms = num_terms + nvar*nz
     221           44 :             if (skip_eqn1 > 0) num_terms = num_terms - nz
     222           44 :             if (skip_eqn2 > 0) num_terms = num_terms - nz
     223              :             if (skip_eqn3 > 0) num_terms = num_terms - nz
     224        52392 :             do k = 1, nz
     225       680568 :                do j = 1, nvar
     226       628176 :                   if (j == skip_eqn1 .or. j == skip_eqn2 .or. j == skip_eqn3) cycle
     227       628176 :                   if (is_bad(s% equ(j,k)) .or. is_bad(s% residual_weight(j,k))) then
     228            0 :                      ierr = 1
     229            0 :                      return
     230              :                   end if
     231       628176 :                   absq = abs(s% equ(j,k)*s% residual_weight(j,k))
     232       628176 :                   sumequ = sumequ + absq
     233       680524 :                   if (absq > equ_max) then
     234         3567 :                      equ_max = absq
     235         3567 :                      j_max = j
     236         3567 :                      k_max = k
     237              :                   end if
     238              :                end do
     239              :             end do
     240              :          else
     241            0 :             if (skip_eqn1 == 0 .and. skip_eqn2 == 0) then
     242            0 :                num_terms = num_terms + nvar_hydro*nz
     243            0 :             else if (skip_eqn1 > 0 .and. skip_eqn2 > 0) then
     244            0 :                num_terms = num_terms + (nvar_hydro-2)*nz
     245              :             else
     246            0 :                num_terms = num_terms + (nvar_hydro-1)*nz
     247              :             end if
     248            0 :             do k = 1, nz
     249            0 :                do j = 1, nvar_hydro
     250            0 :                   if (j == skip_eqn1 .or. j == skip_eqn2) cycle
     251            0 :                   absq = abs(s% equ(j,k)*s% residual_weight(j,k))
     252            0 :                   sumequ = sumequ + absq
     253            0 :                   if (is_bad(sumequ)) then
     254            0 :                      if (dbg) then
     255            0 :                         write(*,3) trim(s% nameofequ(j)) // ' sumequ', j, k, sumequ
     256            0 :                         call mesa_error(__FILE__,__LINE__,'sizeq 1')
     257              :                      end if
     258            0 :                      ierr = -1
     259            0 :                      if (s% report_ierr) &
     260            0 :                         write(*,3) 'bad equ(j,k)*s% residual_weight(j,k) ' // trim(s% nameofequ(j)), &
     261            0 :                            j, k, s% equ(j,k)*s% residual_weight(j,k)
     262            0 :                      if (s% stop_for_bad_nums) call mesa_error(__FILE__,__LINE__,'sizeq 2')
     263            0 :                      return
     264              :                   end if
     265            0 :                   if (absq > equ_max) then
     266            0 :                      equ_max = absq
     267            0 :                      j_max = j
     268            0 :                      k_max = k
     269              :                   end if
     270              :                end do
     271              :             end do
     272              :          end if
     273           44 :          if (s% do_burn .or. s% do_mix) then
     274           44 :             num_terms = num_terms + nvar_chem*nz
     275        52392 :             do k = 1, nz
     276       471176 :                do j = nvar_hydro+1, nvar
     277       418784 :                   absq = abs(s% equ(j,k)*s% residual_weight(j,k))
     278       418784 :                   sumequ = sumequ + absq
     279       471132 :                   if (absq > equ_max) then
     280            0 :                      equ_max = absq
     281            0 :                      j_max = j
     282            0 :                      k_max = k
     283              :                   end if
     284              :                end do
     285              :             end do
     286              :          end if
     287              : 
     288           44 :          equ_norm = sumequ/num_terms
     289           44 :          if (dbg) write(*,4) trim(s% nameofequ(j_max)) // ' sizequ equ_max norm', &
     290            0 :             k_max, s% solver_iter, s% model_number, equ_max, equ_norm
     291              : 
     292            0 :          if (dbg) call dump_equ
     293              : 
     294              :          return
     295              :          call dump_equ
     296              :          call mesa_error(__FILE__,__LINE__,'sizequ')
     297              : 
     298              :          contains
     299              : 
     300            0 :          subroutine dump_equ
     301              :             integer :: k, j
     302              :             include 'formats'
     303            0 :             do k=1,s% nz
     304            0 :                do j=1,nvar
     305            0 :                   write(*,3) 'equ ' // trim(s% nameofequ(j)), &
     306            0 :                      k, s% solver_iter, s% equ(j, k)
     307              :                end do
     308            0 :                write(*,'(A)')
     309              :                !if (k == 6) exit
     310              :             end do
     311            0 :          end subroutine dump_equ
     312              : 
     313              :       end subroutine sizequ
     314              : 
     315              : 
     316           33 :       subroutine sizeB(s, nvar, B, max_correction, correction_norm, max_zone, max_var, ierr)
     317              :          type (star_info), pointer :: s
     318              :          integer, intent(in) :: nvar
     319              :          real(dp), pointer, dimension(:,:) :: B  ! (nvar, nz)
     320              :          real(dp), intent(out) :: correction_norm  ! a measure of the average correction
     321              :          real(dp), intent(out) :: max_correction  ! magnitude of the max correction
     322              :          integer, intent(out) :: max_zone, max_var, ierr
     323              : 
     324              :          integer :: k, i, nz, num_terms, j, n, nvar_hydro, jmax, num_xa_terms, &
     325              :             skip1, skip2, skip3, skip4, skip5
     326           33 :          real(dp) :: abs_corr, sum_corr, sum_xa_corr, x_limit, &
     327           33 :             max_abs_correction, max_abs_corr_for_k, max_abs_xa_corr_for_k
     328              :          logical :: found_NaN, found_bad_num, report
     329              :          real(dp), parameter :: frac = 0.1d0
     330              :          logical, parameter :: dbg = .false.
     331              :          logical, parameter :: check_for_bad_nums = .true.
     332              :          logical, parameter :: save_max_abs_corr_for_k = .true.
     333              : 
     334              :          include 'formats'
     335              : 
     336              :          if (dbg) write(*, *) 'enter sizeB'
     337              : 
     338           33 :          ierr = 0
     339           33 :          nz = s% nz
     340           33 :          n = nz
     341           33 :          nvar_hydro = min(nvar, s% nvar_hydro)
     342              : 
     343           33 :          if (s% include_L_in_correction_limits) then
     344           33 :             skip1 = 0
     345        39294 :             do k=1,nz
     346        39294 :                s% correction_weight(s% i_lum,k) = 1d0/(frac*s% L_start(1) + abs(s% L(k)))
     347              :             end do
     348              :          else
     349            0 :             skip1 = s% i_lum
     350              :          end if
     351              : 
     352           33 :          if (s% u_flag .and. s% include_u_in_correction_limits) then
     353            0 :             skip2 = 0
     354            0 :             do k=1,nz
     355            0 :                s% correction_weight(s% i_u,k) = 1d0/(frac*s% csound_start(k) + abs(s% u(k)))
     356              :             end do
     357           33 :          else if (s% v_flag .and. s% include_v_in_correction_limits) then
     358            0 :             skip2 = 0
     359            0 :             do k=1,nz
     360            0 :                s% correction_weight(s% i_v,k) = 1d0/(frac*s% csound_start(k) + abs(s% v(k)))
     361              :             end do
     362           33 :          else if (s% u_flag) then
     363            0 :             skip2 = s% i_u
     364              :          else
     365           33 :             skip2 = s% i_v
     366              :          end if
     367              : 
     368           33 :          if (s% RSP2_flag .and. s% include_w_in_correction_limits) then
     369            0 :             skip3 = 0
     370            0 :             do k=1,nz
     371            0 :                if (abs(s% w(k)) < 1d0) then
     372            0 :                   s% correction_weight(s% i_w,k) = 0d0
     373              :                else
     374            0 :                   s% correction_weight(s% i_w,k) = 1d0/(1d3 + abs(s% w(k)))  ! don't sweat the small stuff
     375              :                end if
     376              :             end do
     377              :          else
     378           33 :             skip3 = s% i_w
     379              :          end if
     380           33 :          skip4 = s% i_Hp
     381              : 
     382           33 :          skip5 = 0
     383              : 
     384           33 :          max_zone = 0
     385           33 :          max_var = 0
     386           33 :          num_terms = 0
     387           33 :          num_xa_terms = 0
     388           33 :          sum_corr = 0
     389           33 :          sum_xa_corr = 0
     390           33 :          max_correction = 0
     391           33 :          max_abs_correction = 0
     392           33 :          x_limit = s% correction_xa_limit
     393           33 :          found_NaN = .false.
     394           33 :          found_bad_num = .false.
     395           33 :          report = s% report_ierr
     396        39294 :          cell_loop: do k = 1, nz
     397        39261 :             max_abs_corr_for_k = 0
     398        39261 :             max_abs_xa_corr_for_k = 0
     399              : 
     400        39261 :             if (s% do_burn .or. s% do_mix) then
     401              :                jmax = nvar
     402              :             else
     403        39261 :                jmax = nvar_hydro
     404              :             end if
     405       510393 :             var_loop: do j = 1, jmax
     406              :                if (j == skip1 .or. &
     407              :                    j == skip2 .or. &
     408              :                    j == skip3 .or. &
     409              :                    j == skip4 .or. &
     410       471132 :                    j == skip5 .or. &
     411              :                    j == s% i_alpha_RTI) cycle var_loop
     412              :                if (check_for_bad_nums) then
     413       471132 :                   if (is_bad_num(B(j,k)*s% correction_weight(j,k))) then
     414            0 :                      found_bad_num = .true.
     415            0 :                      if (report) write(*,2) 'sizeB: bad num for correction ' // &
     416            0 :                         s% nameofvar(j), k, B(j,k)*s% correction_weight(j,k)
     417            0 :                      if (s% stop_for_bad_nums) then
     418            0 :                         found_NaN = .true.
     419            0 :                         write(*,3) s% nameofvar(j) // ' B(j,k)*s% correction_weight(j,k)', &
     420            0 :                            j, k, B(j,k)*s% correction_weight(j,k)
     421            0 :                         call mesa_error(__FILE__,__LINE__,'sizeB')
     422              :                      end if
     423              : 
     424            0 :                      max_zone = k
     425            0 :                      max_var = j
     426            0 :                      exit cell_loop
     427              : 
     428              :                      cycle var_loop
     429              :                   end if
     430              :                end if
     431       471132 :                if (j > nvar_hydro) then
     432       314088 :                   if (s% xa_start(j-nvar_hydro,k) < x_limit) cycle var_loop
     433              :                end if
     434              : 
     435       280146 :                abs_corr = abs(B(j,k)*s% correction_weight(j,k))
     436       280146 :                if (is_bad_num(abs_corr)) then
     437            0 :                   found_bad_num = .true.
     438            0 :                   if (report) write(*,3) 'B(j,k)*s% correction_weight(j,k)', &
     439            0 :                      j, k, B(j,k)*s% correction_weight(j,k)
     440            0 :                   if (s% stop_for_bad_nums) found_NaN = .true.
     441              :                end if
     442              :                if (abs_corr > max_abs_corr_for_k &
     443              :                   .and. .not. (j > nvar_hydro .and. s% ignore_species_in_max_correction)) &
     444              :                      max_abs_corr_for_k = abs_corr
     445              :                if (abs_corr > max_abs_correction &
     446       280146 :                   .and. .not. (j > nvar_hydro .and. s% ignore_species_in_max_correction)) then
     447        11963 :                   max_correction = B(j,k)*s% correction_weight(j,k)
     448        11963 :                   max_abs_correction = abs_corr
     449        11963 :                   max_zone = k
     450        11963 :                   max_var = j
     451              :                end if
     452       319407 :                if (j > nvar_hydro) then
     453       123102 :                   num_xa_terms = num_xa_terms + 1
     454       123102 :                   sum_xa_corr = sum_xa_corr + abs_corr
     455       123102 :                   if (abs_corr > max_abs_xa_corr_for_k) &
     456        52001 :                      max_abs_xa_corr_for_k = abs_corr
     457              :                else
     458       157044 :                   num_terms = num_terms + 1
     459       157044 :                   sum_corr = sum_corr + abs_corr
     460              :                end if
     461              :             end do var_loop
     462        39261 :             if (num_xa_terms > 0) then
     463        39261 :                num_terms = num_terms + 1
     464        39261 :                sum_corr = sum_corr + sum_xa_corr/num_xa_terms
     465              :             end if
     466        39261 :             if (s% do_burn .or. s% do_mix) then
     467       353349 :                species_loop: do j = nvar_hydro+1, nvar
     468       314088 :                   i = j - s% nvar_hydro
     469              :                   if (check_for_bad_nums) then
     470       314088 :                      if (is_bad_num(B(j,k)*s% correction_weight(j,k))) then
     471            0 :                         found_bad_num = .true.
     472            0 :                         if (report) write(*,3) 'chem B(j,k)*s% correction_weight(j,k)', j, k, &
     473            0 :                            B(j,k)*s% correction_weight(j,k)
     474            0 :                         if (s% stop_for_bad_nums) then
     475            0 :                            found_NaN = .true.
     476            0 :                            write(*,3) 'chem B(j,k)*s% correction_weight(j,k)', &
     477            0 :                               j, k, B(j,k)*s% correction_weight(j,k)
     478            0 :                            call mesa_error(__FILE__,__LINE__,'sizeB')
     479            0 :                         max_zone = k
     480            0 :                         max_var = j
     481            0 :                         exit cell_loop
     482              :                         end if
     483              :                      end if
     484              :                   end if
     485              :                   ! recall that correction dx = B*xscale, so B is a relative correction
     486       353349 :                   if (s% xa_start(i,k) >= x_limit) then
     487       123102 :                      abs_corr = abs(B(j,k)*s% correction_weight(j,k))
     488       123102 :                      if (.not. s% ignore_species_in_max_correction) then
     489              :                         if (abs_corr > max_abs_corr_for_k) max_abs_corr_for_k = abs_corr
     490       123102 :                         if (abs_corr > max_abs_correction) then
     491            0 :                            max_abs_correction = abs_corr
     492            0 :                            max_correction = B(j,k)*s% correction_weight(j,k)
     493            0 :                            max_zone = k
     494            0 :                            max_var = j
     495              :                         end if
     496              :                      end if
     497       123102 :                      sum_corr = sum_corr + abs_corr
     498       123102 :                      num_terms = num_terms + 1
     499              :                   end if
     500              :                end do species_loop
     501              :             end if
     502        39294 :             s% max_abs_xa_corr(k) = max_abs_xa_corr_for_k
     503              :          end do cell_loop
     504              : 
     505           33 :          if (found_bad_num) then
     506            0 :             ierr = -1
     507            0 :             if (found_NaN .and. s% stop_for_bad_nums) then
     508            0 :                write(*,*) 'found bad num'
     509            0 :                call mesa_error(__FILE__,__LINE__,'sizeB')
     510              :             end if
     511           22 :             if (.not. dbg) return
     512              :          end if
     513              : 
     514           33 :          if (is_bad_num(sum_corr)) then
     515            0 :             ierr = -1
     516            0 :             if (s% stop_for_bad_nums) then
     517            0 :                if (report) write(*,*) 'sum_corr', sum_corr
     518            0 :                call mesa_error(__FILE__,__LINE__,'sizeB')
     519              :             end if
     520            0 :             if (.not. dbg) return
     521              :             write(*,*) 'sum_corr', sum_corr
     522              :             call mesa_error(__FILE__,__LINE__,'sizeB')
     523              :          end if
     524              : 
     525           33 :          correction_norm = sum_corr/num_terms  !sqrt(sum_corr/num_terms)
     526              :          if (dbg) then
     527              :             write(*,2) 'sizeB: iter, correction_norm, max_correction', &
     528              :                s% solver_iter, correction_norm, max_correction
     529              :             if (max_correction > 1d50 .or. is_bad_num(correction_norm)) then
     530              :                call show_stuff
     531              :                call mesa_error(__FILE__,__LINE__,'sizeB')
     532              :             end if
     533              :          end if
     534              : 
     535           33 :          if (s% solver_show_correction_info) call show_stuff
     536              : 
     537           33 :          abs_corr = max_abs_correction
     538              : 
     539           33 :          s% abs_max_corr2 = s% abs_max_corr1; s% abs_max_corr1 = abs_corr
     540           33 :          s% max_var2 = s% max_var1; s% max_var1 = max_var
     541           33 :          s% max_zone2 = s% max_zone1; s% max_zone1 = max_zone
     542              : 
     543           33 :          if (ierr /= 0) call mesa_error(__FILE__,__LINE__,'ierr in sizeB')
     544              : 
     545           33 :          if (is_bad_num(max_correction)) then
     546            0 :             ierr = -1
     547            0 :             if (s% stop_for_bad_nums) then
     548            0 :                if (report) write(*,*) 'max_correction', max_correction
     549            0 :                call mesa_error(__FILE__,__LINE__,'sizeB')
     550              :             end if
     551            0 :             if (.not. dbg) return
     552              :             write(*,*) 'max_correction', max_correction
     553              :             call mesa_error(__FILE__,__LINE__,'sizeB')
     554              :          end if
     555              : 
     556           33 :          if (s% solver_iter < 3) return
     557              :          ! check for flailing
     558              :          if ( &
     559              :              abs_corr > s% tol_max_correction .and. &
     560              :              abs_corr > s% abs_max_corr1 .and. s% abs_max_corr1 > s% abs_max_corr2 .and. &
     561              :              max_zone == s% max_zone1 .and. s% max_zone1 == s% max_zone2 .and. &
     562           11 :              max_var == s% max_var1 .and. s% max_var1 == s% max_var2) then
     563            0 :             if (s% solver_show_correction_info) then
     564            0 :                write(*,*) 'give up because diverging'
     565              :             end if
     566            0 :             max_correction = 1d99
     567              :          end if
     568              : 
     569              : 
     570              :          contains
     571              : 
     572              : 
     573            0 :          subroutine show_stuff
     574              :             integer :: j, k
     575            0 :             real(dp) :: dx, prev, new
     576              :             include 'formats'
     577            0 :             if (s% solver_iter == 1) then
     578            0 :                write(*,'(A)')
     579              :                write(*,'(4a7,12a16,99a13)') &
     580            0 :                   'model', 'iter', 'var', 'zone', &
     581            0 :                   'corr norm', 'max corr', 'xscale', &
     582            0 :                   'dx', 'new-prev', 'new', 'prev', &
     583            0 :                   'mass loc', 'log dt/yr', 'lgE', 'lgT', 'lgRho'
     584              :             end if
     585            0 :             k = max_zone
     586            0 :             j = max_var
     587            0 :             if (j > nvar_hydro) then
     588            0 :                prev = s% xa_start(j - nvar_hydro,k)
     589              :             else
     590            0 :                prev = s% xh_start(j,k)
     591              :             end if
     592            0 :             dx = B(j,k)*s% correction_weight(j,k)*s% x_scale(j,k)
     593            0 :             new = prev + dx
     594              :             write(*,'(2i7,a7,i7,12e16.8,99f13.8)') &
     595            0 :                s% model_number, s% solver_iter, trim(s% nameofvar(max_var)), k, &
     596            0 :                correction_norm, B(j,k)*s% correction_weight(j,k), s% x_scale(j,k), &
     597            0 :                dx, new - prev, new, prev, &
     598            0 :                s% m(k)/Msun, log10(s% dt/secyer), &
     599            0 :                s% lnE(k)/ln10, s% lnT(k)/ln10, &
     600            0 :                s% lnd(k)/ln10
     601            0 :          end subroutine show_stuff
     602              : 
     603              : 
     604              :          subroutine dump_B
     605              :             integer :: k, j
     606              :             include 'formats'
     607              :             do k=1,s% nz
     608              :                do j=1,nvar
     609              :                   write(*,2) 'B ' // trim(s% nameofequ(j)), k, B(j, k)
     610              :                end do
     611              :                write(*,'(A)')
     612              :             end do
     613              :             call mesa_error(__FILE__,__LINE__,'dump_equ')
     614              :          end subroutine dump_B
     615              : 
     616              : 
     617              :       end subroutine sizeB
     618              : 
     619              : 
     620              :       ! the proposed change to dx is B*xscale*correction_factor
     621              :       ! edit correction_factor and/or B as necessary so that the new dx will be valid.
     622              :       ! set ierr nonzero if things are beyond repair.
     623           33 :       subroutine Bdomain(s, nvar, B, correction_factor, ierr)
     624              :          use const_def, only: dp
     625              :          use chem_def, only: chem_isos
     626              :          use star_utils, only: current_min_xa_hard_limit, rand
     627              :          type (star_info), pointer :: s
     628              :          integer, intent(in) :: nvar
     629              :          real(dp), pointer, dimension(:,:) :: B  ! (nvar, nz)
     630              :          real(dp), intent(inout) :: correction_factor
     631              :          integer, intent(out) :: ierr
     632              :          integer :: i, j, k, nz, species, bad_j, bad_k
     633           33 :          real(dp) :: alpha, min_alpha, new_xa, old_xa, dxa, eps, min_xa_hard_limit, &
     634           33 :             dlum_surf, old_lum_surf, new_lum_surf
     635              :          include 'formats'
     636           33 :          ierr = 0
     637           33 :          min_alpha = 1d0
     638           33 :          nz = s% nz
     639              : 
     640           33 :          if (s% RSP2_flag) &  ! clip change in w to maintain non-negativity.
     641            0 :             call clip_so_non_negative(s% i_w, 0d0)
     642              : 
     643           33 :          if (s% RTI_flag) &  ! clip change in alpha_RTI to maintain non-negativity.
     644            0 :             call clip_so_non_negative(s% i_alpha_RTI, 0d0)
     645              : 
     646           33 :          if (s% i_lum>=0 .and. s% scale_max_correction_for_negative_surf_lum) then
     647              :             !ensure surface luminosity does not become negative
     648            0 :             dlum_surf = B(s% i_lum,1)*s% x_scale(s% i_lum,1)
     649            0 :             old_lum_surf = s% xh_start(s% i_lum,1) + s% solver_dx(s% i_lum,1)
     650            0 :             new_lum_surf = old_lum_surf + dlum_surf
     651            0 :             if (new_lum_surf < 0d0 .and. old_lum_surf > 0d0) then
     652              :                correction_factor = min(correction_factor, &
     653            0 :                   -s% max_frac_for_negative_surf_lum*old_lum_surf/dlum_surf)
     654              :             end if
     655              :          end if
     656              : 
     657              :          !if (s% w_div_wc_flag) then
     658              :          !   do k=1,nz
     659              :          !      old_xa = s% xh_start(s% i_w_div_wc,k) + dx(s% i_w_div_wc,k)
     660              :          !      dxa = B(s% i_w_div_wc,k)*xscale(s% i_w_div_wc,k)*correction_factor
     661              :          !      if (dxa > 0.9d0*(1-old_xa)) then
     662              :          !         if(k==91)write(*,*) "problems", old_xa, dxa, old_xa+dxa
     663              :          !         correction_factor = min(correction_factor,(0.9d0*(1-old_xa))/B(s% i_w_div_wc,k)*xscale(s%i_w_div_wc,k))
     664              :          !         dxa = B(s% i_w_div_wc,k)*xscale(s% i_w_div_wc,k)*correction_factor
     665              :          !         if(k==91)write(*,*) "need to reduce correction", k, old_xa+dxa
     666              :          !      end if
     667              :          !   end do
     668              :          !end if
     669              : 
     670           33 :          if ((.not. s% do_solver_damping_for_neg_xa) .or. &
     671              :              (.not. (s% do_mix .or. s% do_burn))) then
     672              :             if (min_alpha < 1d0) then
     673              :                min_alpha = max(min_alpha, s% corr_coeff_limit)
     674              :                correction_factor = min_alpha*correction_factor
     675              :             end if
     676              :             return
     677              :          end if
     678              : 
     679           33 :          bad_j = 0
     680           33 :          bad_k = 0
     681           33 :          if (nvar > s% nvar_hydro) then
     682           33 :             species = s% species
     683           33 :             min_xa_hard_limit = current_min_xa_hard_limit(s)
     684           33 :             eps = -0.5d0*min_xa_hard_limit  ! allow xa to be this much below 0d0
     685        39294 :             do k=1,nz
     686       353382 :                do j=1,species
     687       314088 :                   i = j + s% nvar_hydro
     688       314088 :                   old_xa = s% xa_start(j,k) + s% solver_dx(i,k)
     689       314088 :                   if (old_xa <= 1d-90) cycle
     690       314088 :                   dxa = B(i,k)*s% x_scale(i,k)*correction_factor
     691       314088 :                   new_xa = old_xa + dxa
     692       314088 :                   if (new_xa >= 0d0) cycle
     693            0 :                   alpha = -(old_xa + eps)/dxa
     694              :                   ! so dxa*alpha = -old_xa - eps,
     695              :                   ! and therefore old_xa + alpha*dxa = -eps = 0.5*min_xa_hard_limit
     696        39261 :                   if (alpha < min_alpha) then
     697            0 :                      min_alpha = alpha
     698            0 :                      bad_j = j
     699            0 :                      bad_k = k
     700              :                   end if
     701              :                end do
     702              :             end do
     703              :          end if
     704              : 
     705           33 :          min_alpha = max(min_alpha, s% corr_coeff_limit)
     706           33 :          correction_factor = min_alpha*correction_factor
     707           33 :          if (s% trace_solver_damping .and. min_alpha < 1d0 .and. bad_j > 0) then
     708              :             write(*,4) 'solver damping to avoid negative mass fractions: ' // &
     709            0 :                trim(chem_isos% name(s% chem_id(bad_j))), bad_k, &
     710            0 :                s% model_number, s% solver_iter, min_alpha
     711              :          end if
     712              : 
     713              :          contains
     714              : 
     715            0 :          subroutine clip_so_non_negative(i,minval)
     716              :             integer, intent(in) :: i
     717              :             real(dp), intent(in) :: minval
     718            0 :             real(dp) :: dval, old_val, new_val
     719            0 :             do k = 1, s% nz
     720            0 :                dval = B(i,k)*s% x_scale(i,k)*correction_factor
     721            0 :                old_val = s% xh_start(i,k) + s% solver_dx(i,k)
     722            0 :                new_val = old_val + dval
     723            0 :                if (dval >= 0) cycle
     724            0 :                if (new_val >= 0d0) cycle
     725            0 :                dval = minval - old_val
     726            0 :                B(i,k) = dval/(s% x_scale(i,k)*correction_factor)
     727              :             end do
     728           33 :          end subroutine clip_so_non_negative
     729              : 
     730              :       end subroutine Bdomain
     731              : 
     732              : 
     733           33 :       subroutine inspectB(s, nvar, B, ierr)
     734              :          type (star_info), pointer :: s
     735              :          integer, intent(in) :: nvar
     736              :          real(dp), pointer, dimension(:,:) :: B  ! (nvar, nz)
     737              :          integer, intent(out) :: ierr
     738              : 
     739              :          integer, parameter :: inspectB_iter_stop = -1
     740              :          include 'formats'
     741              : 
     742              :          if (dbg) write(*, *) 'inspectB', s% solver_iter
     743           33 :          ierr = 0
     744           33 :          if (s% solver_iter == inspectB_iter_stop) then
     745            0 :             call dumpB
     746            0 :             call mesa_error(__FILE__,__LINE__,'debug: inspectB')
     747              :          end if
     748              : 
     749              :          contains
     750              : 
     751            0 :          subroutine dumpB
     752              :             integer :: k, j
     753              :             include 'formats'
     754            0 :             do k=1,s% nz
     755            0 :                do j=1,nvar
     756            0 :                   write(*,2) 'B ' // trim(s% nameofvar(j)), k, B(j, k)
     757            0 :                   write(*,2) 'xscale ' // trim(s% nameofvar(j)), k, s% x_scale(j, k)
     758            0 :                   write(*,2) 'dx ' // trim(s% nameofvar(j)), k, s% solver_dx(j, k)
     759              :                end do
     760            0 :                write(*,'(A)')
     761              :             end do
     762            0 :             call mesa_error(__FILE__,__LINE__,'dumpB')
     763            0 :          end subroutine dumpB
     764              : 
     765              :       end subroutine inspectB
     766              : 
     767              : 
     768              :       ! about to declare victory... but may want to do another iteration
     769              :       ! 1 means force another iteration
     770              :       ! 0 means don't need to force another
     771              :       ! -1 means failure. solver returns with non-convergence.
     772           11 :       integer function force_another_iteration(s, iter, itermin)
     773              :          type (star_info), pointer :: s
     774              :          integer, intent(in) :: iter  ! have finished this many iterations and have converged
     775              :          integer, intent(in) :: itermin  ! this is the requested minimum.  iter may be < itermin.
     776              : 
     777              :          include 'formats'
     778              : 
     779           11 :          if (iter < itermin) then
     780            0 :             force_another_iteration = 1
     781              :             return
     782              :          end if
     783           11 :          force_another_iteration = 0
     784              : 
     785              :          if (s% k_below_just_added > 1 .and. &
     786           11 :                s% num_surf_revisions < s% max_num_surf_revisions .and. &
     787              :                abs(s% lnS(1) - s% surf_lnS) > &
     788              :                   s% max_abs_rel_change_surf_lnS*max(s% lnS(1),s% surf_lnS)) then
     789            0 :             s% surf_lnS = s% lnS(1)
     790            0 :             s% num_surf_revisions = s% num_surf_revisions + 1
     791            0 :             force_another_iteration = 1
     792            0 :             s% used_extra_iter_in_solver_for_accretion = .true.
     793            0 :             return
     794              :          end if
     795              : 
     796              :       end function force_another_iteration
     797              : 
     798              : 
     799           33 :       subroutine set_solver_vars(s, nvar, dt, ierr)
     800              :          type (star_info), pointer :: s
     801              :          integer, intent(in) :: nvar
     802              :          real(dp), intent(in) :: dt
     803              :          integer, intent(out) :: ierr
     804           33 :          s% num_solver_setvars = s% num_solver_setvars + 1
     805           33 :          call set_vars_for_solver(s, nvar, 1, s% nz, dt, ierr)
     806           33 :       end subroutine set_solver_vars
     807              : 
     808              : 
     809           33 :       subroutine set_vars_for_solver(s, nvar, nzlo, nzhi, dt, ierr)
     810              :          use const_def, only: secyer, Msun, Lsun, Rsun
     811              :          use star_utils, only: set_rmid, set_dm_bar, set_m_and_dm, set_rv_info
     812              :          use star_utils, only: current_min_xa_hard_limit, current_sum_xa_hard_limit, &
     813              :             lookup_nameofvar
     814              :          use hydro_vars, only: set_hydro_vars
     815              :          use hydro_rotation, only: set_i_rot, set_omega
     816              :          use mix_info, only: get_convection_sigmas
     817              :          use chem_def
     818              :          type (star_info), pointer :: s
     819              :          integer, intent(in) :: nvar, nzlo, nzhi
     820              :          real(dp), intent(in) :: dt
     821              :          integer, intent(out) :: ierr
     822              : 
     823              :          logical, parameter :: &
     824              :             skip_basic_vars = .true., &
     825              :             skip_micro_vars = .false., &
     826              :             skip_kap = .false., &
     827              :             skip_neu = .false., &
     828              :             skip_net = .false., &
     829              :             skip_eos = .false., &
     830              :             skip_mlt = .false., &
     831              :             skip_grads = .true., &
     832              :             skip_rotation = .true., &
     833              :             skip_m_grav_and_grav = .true., &
     834              :             skip_brunt = .true., &
     835              :             skip_mixing_info = .true., &
     836              :             skip_set_cz_bdy_mass = .true., &
     837              :             skip_other_cgrav = .true.
     838              :          logical :: do_chem, try_again, do_edit_lnR, report_dx
     839              :          integer :: j, k, kk, klo, khi, i_var, &
     840              :             i_lnd, i_lnT, i_lnR, i_lum, i_w, i_Hp, i_v, &
     841              :             i_u, i_alpha_RTI, i_w_div_wc, i_j_rot, &
     842              :             fe56, nvar_chem, species, nz, nvar_hydro
     843           33 :          real(dp), dimension(:, :), pointer :: xh_start, xa_start
     844              :          integer :: op_err, kbad, &
     845              :             cnt, max_fixes, loc(2), k_lo, k_hi
     846           33 :          real(dp) :: xavg, dx_for_i_var, x_for_i_var, &
     847           33 :             dq_sum, d_dxdt_dx, min_xa_hard_limit, sum_xa_hard_limit
     848              :          logical :: do_lnd, do_lnT, do_lnR, do_lum, do_w, &
     849              :             do_u, do_v, do_alpha_RTI, do_w_div_wc, do_j_rot
     850              : 
     851              :          include 'formats'
     852              : 
     853           33 :          ierr = 0
     854              : 
     855           33 :          nz = s% nz
     856           33 :          nvar_chem = s% nvar_chem
     857           33 :          species = s% species
     858           33 :          nvar_hydro = s% nvar_hydro
     859           33 :          d_dxdt_dx = 1d0/s% dt
     860              : 
     861           33 :          xh_start => s% xh_start
     862           33 :          xa_start => s% xa_start
     863              : 
     864              :          report_dx = &
     865              :             s% solver_test_partials_dx_0 > 0d0 .and. &
     866              :             s% solver_test_partials_k > 0 .and. &
     867              :             s% solver_call_number == s% solver_test_partials_call_number .and. &
     868              :             s% solver_test_partials_iter_number == s% solver_iter .and. &
     869            0 :             len_trim(s% solver_test_partials_show_dx_var_name) > 0
     870              : 
     871              :          if (report_dx) then
     872            0 :             k = s% solver_test_partials_k
     873            0 :             i_var = lookup_nameofvar(s, s% solver_test_partials_show_dx_var_name)
     874            0 :             if (i_var > 0) then
     875            0 :                if (i_var > nvar_hydro) then
     876            0 :                   dx_for_i_var = s% solver_dx(i_var,k)
     877            0 :                   x_for_i_var = xa_start(i_var-nvar_hydro,k) + s% solver_dx(i_var,k)
     878              :                else
     879            0 :                   dx_for_i_var = s% solver_dx(i_var,k)
     880            0 :                   x_for_i_var = xh_start(i_var,k) + s% solver_dx(i_var,k)
     881              :                end if
     882              :                write(*,3) 'dx, x for var name ' // &
     883            0 :                   trim(s% solver_test_partials_show_dx_var_name), &
     884            0 :                   k, s% solver_iter, dx_for_i_var, x_for_i_var
     885              :             end if
     886              :          end if
     887              : 
     888           33 :          do_chem = (s% do_burn .or. s% do_mix)
     889              : 
     890              :          if (dbg .and. .not. skip_mixing_info) write(*,2) 'redo mix info iter', s% solver_iter
     891              : 
     892           33 :          min_xa_hard_limit = current_min_xa_hard_limit(s)
     893           33 :          sum_xa_hard_limit = current_sum_xa_hard_limit(s)
     894              : 
     895           33 :          i_lnd = s% i_lnd
     896           33 :          i_lnT = s% i_lnT
     897           33 :          i_lnR = s% i_lnR
     898           33 :          i_lum = s% i_lum
     899           33 :          i_w = s% i_w
     900           33 :          i_Hp = s% i_Hp
     901           33 :          i_v = s% i_v
     902           33 :          i_u = s% i_u
     903           33 :          i_alpha_RTI = s% i_alpha_RTI
     904           33 :          i_w_div_wc = s% i_w_div_wc
     905           33 :          i_j_rot = s% i_j_rot
     906              : 
     907           33 :          do_lnd = i_lnd > 0 .and. i_lnd <= nvar
     908           33 :          do_lnT = i_lnT > 0 .and. i_lnT <= nvar
     909           33 :          do_lnR = i_lnR > 0 .and. i_lnR <= nvar
     910           33 :          do_lum = i_lum > 0 .and. i_lum <= nvar
     911           33 :          do_w = i_w > 0 .and. i_w <= nvar
     912           33 :          do_v = i_v > 0 .and. i_v <= nvar
     913           33 :          do_u = i_u > 0 .and. i_u <= nvar
     914           33 :          do_alpha_RTI = i_alpha_RTI > 0 .and. i_alpha_RTI <= nvar
     915           33 :          do_w_div_wc = i_w_div_wc > 0 .and. i_w_div_wc <= nvar
     916           33 :          do_j_rot = i_j_rot > 0 .and. i_j_rot <= nvar
     917              : 
     918           33 :          fe56 = s% net_iso(ife56)
     919              :          if (fe56 /= 0) fe56 = nvar_hydro+fe56
     920              : 
     921           33 :          if (nvar > nvar_hydro) then
     922        39294 :             do k=1,nz
     923       353382 :                do j=1,species
     924       314088 :                   s% xa_sub_xa_start(j,k) = s% solver_dx(j+nvar_hydro,k)
     925       353349 :                   s% xa(j,k) = xa_start(j,k) + s% solver_dx(j+nvar_hydro,k)
     926              :                end do
     927              :             end do
     928              :             max_fixes = 0  !5
     929              :             do cnt=1,max_fixes
     930              :                loc = minloc(s% xa(1:species,1:nz))
     931              :                j = loc(1)
     932              :                k = loc(2)
     933              :                if (s% xa(j,k) >= 1d-3*min_xa_hard_limit) exit  ! too good to fix
     934              :                if (s% xa(j,k) < min_xa_hard_limit) then
     935              :                   if (s% report_ierr) then
     936              :                      khi = nz
     937              :                      do kk=k+1,nz
     938              :                         if (s% xa(j,kk) < min_xa_hard_limit) cycle
     939              :                         khi = kk-1; exit
     940              :                      end do
     941              :                      klo = 1
     942              :                      do kk=k-1,1,-1
     943              :                         if (s% xa(j,kk) < min_xa_hard_limit) cycle
     944              :                         klo = kk+1; exit
     945              :                      end do
     946              :                      do k=klo,khi
     947              :                         write(*,2) &
     948              :                            'negative ' // trim(chem_isos% name(s% chem_id(j))), &
     949              :                            k, s% xa(j,k), xa_start(j,k), s% solver_dx(nvar_hydro+j,k), s% m(k)/Msun
     950              :                      end do
     951              :                   end if
     952              :                   s% retry_message = 'some abundance < min_xa_hard_limit'
     953              :                   ierr = -1
     954              :                   return
     955              :                   exit  ! too bad to fix
     956              :                end if
     957              :                if (k == 1) then
     958              :                   k_lo = 1; k_hi = 2
     959              :                else if (k == nz) then
     960              :                   k_lo = nz-1; k_hi = nz
     961              :                else if (s% sig(k) > s% sig(k+1)) then
     962              :                   k_lo = k-1; k_hi = k
     963              :                else if (s% sig(k+1) > 0) then
     964              :                   k_lo = k; k_hi = k+1
     965              :                else
     966              :                   exit
     967              :                end if
     968              :                try_again = .true.
     969              :                do while (try_again .and. sum(s% xa(j,k_lo:k_hi)*s% dq(k_lo:k_hi)) < 0)
     970              :                   try_again = .false.
     971              :                   if (k_lo > 1) then
     972              :                      if (s% sig(k_lo) > 0) then
     973              :                         k_lo = k_lo-1
     974              :                         try_again = .true.
     975              :                      end if
     976              :                   end if
     977              :                   if (k_hi < nz) then
     978              :                      if (s% sig(k_hi+1) > 0) then
     979              :                         k_hi = k_hi+1
     980              :                         try_again = .true.
     981              :                      end if
     982              :                   end if
     983              :                end do
     984              :                !write(*,3) 'no extend', k_lo, k_hi
     985              :                if (.not. try_again) exit
     986              :                dq_sum = sum(s% dq(k_lo:k_hi))
     987              :                if (s% report_ierr) then
     988              :                   write(*,5) 'fix xa(j,k_lo:k_hi)', j, k_lo, k, k_hi, s% xa(j,k), &
     989              :                      sum(s% xa(j,k_lo:k_hi)*s% dq(k_lo:k_hi))/dq_sum, dq_sum
     990              :                   !stop
     991              :                 end if
     992              :                do j=1,species
     993              :                   xavg = sum(s% xa(j,k_lo:k_hi)*s% dq(k_lo:k_hi))/dq_sum
     994              :                   do kk=k_lo,k_hi
     995              :                      s% xa(j,kk) = xavg
     996              :                   end do
     997              :                end do
     998              :             end do
     999              :          end if
    1000              : 
    1001           33 :          if (s% solver_test_partials_k > 0 .and. &
    1002              :              s% solver_test_partials_k <= nz) then
    1003            0 :             k = s% solver_test_partials_k
    1004              :          end if
    1005              : 
    1006           33 :          kbad = 0
    1007           33 : !$OMP PARALLEL DO PRIVATE(k,op_err) SCHEDULE(dynamic,2)
    1008              :          do k=1,nz
    1009              :             op_err = 0
    1010              :             call set1(k,.false.,op_err)
    1011              :             if (op_err /= 0) then
    1012              :                kbad = k; ierr = op_err
    1013              :             end if
    1014              :          end do
    1015              : !$OMP END PARALLEL DO
    1016              : 
    1017           33 :          if (ierr /= 0) then
    1018            0 :             if (s% report_ierr) then
    1019            0 :                do k=1,nz  ! report the errors sequentially
    1020            0 :                   call set1(k,.true.,op_err)
    1021              :                end do
    1022            0 :                write(*,3) 'set_vars_for_solver failed: model, nz', &
    1023            0 :                   s% model_number, nz  ! kbad depends on num threads
    1024              :             end if
    1025            0 :             return
    1026              :          end if
    1027              : 
    1028           33 :          if (s% solver_test_partials_k > 0 .and. &
    1029              :              s% solver_test_partials_k <= nz) then
    1030            0 :             k = s% solver_test_partials_k
    1031              :          end if
    1032              : 
    1033           33 :          if (do_lum) then
    1034        39294 :             do k=1,nz
    1035        39294 :                if (is_bad_num(s% L(k))) then
    1036            0 :                   if (s% report_ierr) write(*,2) 'set_vars_for_solver L', k, s% L(k), &
    1037            0 :                      xh_start(i_lum,k) + s% solver_dx(i_lum,k), &
    1038            0 :                      xh_start(i_lum,k), s% solver_dx(i_lum,k)
    1039            0 :                   s% retry_message = 'bad num for some L'
    1040            0 :                   ierr = -1
    1041            0 :                   if (s% stop_for_bad_nums) then
    1042            0 :                      write(*,2) 'set_vars_for_solver L', k, s% L(k)
    1043            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1044              :                   end if
    1045            0 :                   return
    1046              :                   stop
    1047              :                end if
    1048              :             end do
    1049              :          end if
    1050              : 
    1051           33 :          if (ierr /= 0) then
    1052            0 :             if (s% report_ierr) then
    1053              : 
    1054            0 :                do k=1,nz
    1055            0 :                   if (abs(1d0 - sum(s% xa(:,k))) > 1d-3) then
    1056            0 :                      write(*,2) 'set_vars_for_solver: bad xa sum', k, &
    1057            0 :                         sum(s% xa(:,k)), sum(xa_start(:,k)), sum(s% solver_dx(nvar_hydro+1:nvar,k))
    1058            0 :                      write(*,'(51x,a)') 'xa, xa_start+dx, xa_start, dx'
    1059            0 :                      do j=1,species
    1060            0 :                         write(*,2) trim(chem_isos% name(s% chem_id(j))), k, &
    1061            0 :                            s% xa(j,k), xa_start(j,k) + s% solver_dx(nvar_hydro+j,k), &
    1062            0 :                            xa_start(j,k), s% solver_dx(nvar_hydro+j,k)
    1063              :                      end do
    1064              : 
    1065              :                      exit
    1066              : 
    1067              :                   end if
    1068              :                end do
    1069            0 :                write(*,'(A)')
    1070              : 
    1071              :             end if
    1072            0 :             return
    1073              :          end if
    1074              : 
    1075           33 :          do_edit_lnR = do_lnR .and. (.not. s% doing_check_partials)
    1076           33 :          if (do_edit_lnR) call edit_lnR(s, xh_start, s% solver_dx)
    1077        39294 :          do k=1,nz
    1078        39261 :             if (do_edit_lnR) s% r(k) = exp(s% lnR(k))
    1079        39261 :             call set_rv_info(s,k)
    1080              :             ! note: m_grav is held constant during solver iterations
    1081        39294 :             s% grav(k) = s% cgrav(k)*s% m_grav(k)/(s% r(k)*s% r(k))
    1082              :          end do
    1083              : 
    1084           33 :          if (do_lnR) then
    1085           33 :             call set_rmid(s, 1, nz, ierr)
    1086           33 :             if (ierr /= 0) then
    1087            0 :                if (s% report_ierr) write(*, *) 'set_rmid returned ierr', ierr
    1088            0 :                return
    1089              :             end if
    1090              :          end if
    1091              : 
    1092              :          if (dbg) write(*, *) 'call set_hydro_vars'
    1093              :          call set_hydro_vars( &
    1094              :             s, 1, nz, skip_basic_vars, skip_micro_vars, &
    1095              :             skip_m_grav_and_grav, skip_eos, skip_net, skip_neu, skip_kap, &
    1096              :             skip_grads, skip_rotation, skip_brunt, skip_other_cgrav, &
    1097           33 :             skip_mixing_info, skip_set_cz_bdy_mass, skip_mlt, ierr)
    1098           33 :          if (ierr /= 0) then
    1099            0 :             if (s% report_ierr) write(*,2) 'set_hydro_vars returned ierr', ierr
    1100            0 :             return
    1101              :          end if
    1102              : 
    1103           66 :          if (s% rotation_flag) then
    1104              :             ! Moments of inertia are kept fixed as those at the start of the hydro solver
    1105              :             ! neither omege nor irot enter the equations directly
    1106              :          !   call set_i_rot(s)
    1107            0 :             call set_omega(s, 'hydro_mtx')
    1108              :          end if
    1109              : 
    1110              : 
    1111              :          contains
    1112              : 
    1113              : 
    1114        39261 :          subroutine set1(k,report,ierr)
    1115              :             !use chem_def, only: chem_isos
    1116              :             integer, intent(in) :: k
    1117              :             logical, intent(in) :: report
    1118              :             integer, intent(out) :: ierr
    1119              : 
    1120       510393 :             real(dp) :: x(nvar)
    1121              :             ! setting x = xh_start + dx is necessary because of numerical issues.
    1122              :             ! we want to ensure that we've calculated the variables using exactly the
    1123              :             ! same values for x as will be returned as the final result.
    1124              :             integer :: j, k_below_just_added
    1125        39261 :             real(dp) :: v
    1126              : 
    1127              :             include 'formats'
    1128        39261 :             ierr = 0
    1129        39261 :             v = 0
    1130              : 
    1131        39261 :             k_below_just_added = 1
    1132              : 
    1133       196305 :             do j=1,min(nvar, nvar_hydro)
    1134       196305 :                x(j) = xh_start(j,k) + s% solver_dx(j,k)
    1135              :                !write(*,2) 'new ' // s% nameofvar(j), k, x(j)
    1136              :             end do
    1137              : 
    1138        39261 :             if (do_lnT) then
    1139              : 
    1140        39261 :                s% lnT(k) = x(i_lnT)
    1141        39261 :                s% T(k) = exp(s% lnT(k))
    1142        39261 :                s% dxh_lnT(k) = s% solver_dx(i_lnT,k)
    1143              :                if (abs(s% lnT(k) - s% lnT_start(k)) > &
    1144        39261 :                        ln10*s% hydro_mtx_max_allowed_abs_dlogT .and. &
    1145              :                     s% min_logT_for_hydro_mtx_max_allowed < &
    1146              :                      ln10*min(s% lnT(k),s% lnT_start(k))) then
    1147            0 :                   if (report) &
    1148            0 :                      write(*,4) 'hydro_mtx: change too large, dlogT, logT, logT_start', &
    1149            0 :                         s% model_number, k, s% solver_iter, &
    1150            0 :                         (s% lnT(k) - s% lnT_start(k))/ln10, &
    1151            0 :                         s% lnT(k)/ln10, s% lnT_start(k)/ln10
    1152            0 :                   write(s% retry_message, *) 'abs(dlogT) > hydro_mtx_max_allowed_abs_dlogT', k
    1153            0 :                   ierr = -1
    1154            0 :                   return
    1155              :                end if
    1156        39261 :                if (s% lnT(k) > ln10*s% hydro_mtx_max_allowed_logT .and. &
    1157              :                     s% min_logT_for_hydro_mtx_max_allowed < &
    1158              :                      ln10*min(s% lnT(k),s% lnT_start(k))) then
    1159            0 :                   if (report) &
    1160            0 :                      write(*,4) 'hydro_mtx: logT too large', &
    1161            0 :                         s% model_number, k, s% solver_iter, &
    1162            0 :                         s% lnT(k)/ln10, s% lnT_start(k)/ln10
    1163            0 :                   write(s% retry_message, *) 'logT > hydro_mtx_max_allowed_logT', k
    1164            0 :                   ierr = -1
    1165            0 :                   return
    1166              :                end if
    1167        39261 :                if (s% lnT(k) < ln10*s% hydro_mtx_min_allowed_logT) then
    1168            0 :                   if (report) &
    1169            0 :                      write(*,4) 'hydro_mtx: logT too small', &
    1170            0 :                         s% model_number, k, s% solver_iter, &
    1171            0 :                         s% lnT(k)/ln10, s% lnT_start(k)/ln10
    1172            0 :                   write(s% retry_message, *) 'logT < hydro_mtx_min_allowed_logT', k
    1173            0 :                   ierr = -1
    1174            0 :                   return
    1175              :                end if
    1176        39261 :                s% T(k) = exp(s% lnT(k))
    1177        39261 :                if (is_bad_num(s% T(k))) then
    1178            0 :                   s% retry_message = 'bad num for T'
    1179            0 :                   if (s% stop_for_bad_nums) then
    1180            0 :                      write(*,2) 'set_vars_for_solver T', k, s% T(k)
    1181            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1182              :                   end if
    1183            0 :                   if (report) write(*,2) 'bad num T', k, s% T(k)
    1184            0 :                   ierr = -1
    1185              :                end if
    1186              : 
    1187              :             end if
    1188              : 
    1189        39261 :             if (do_lum) then
    1190        39261 :                s% L(k) = x(i_lum)
    1191        39261 :                if (is_bad_num(s% L(k))) then
    1192            0 :                   s% retry_message = 'bad num for L'
    1193            0 :                   ierr = -1
    1194            0 :                   if (s% stop_for_bad_nums) then
    1195            0 :                      write(*,2) 'set_vars_for_solver L', k, s% L(k)
    1196            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1197              :                   end if
    1198            0 :                   if (report) write(*,2) 'bad num L', k, s% L(k)
    1199              :                end if
    1200              :             end if
    1201              : 
    1202        39261 :             if (do_w) then
    1203            0 :                s% w(k) = x(i_w)
    1204            0 :                if (s% w(k) < 0d0) then
    1205              :                   !write(*,4) 'set_vars_for_solver: fix w < 0', k, &
    1206              :                   !   s% solver_iter, s% model_number, s% w(k)
    1207            0 :                   s% w(k) = s% RSP2_w_fix_if_neg
    1208              :                end if
    1209            0 :                if (is_bad_num(s% w(k))) then
    1210            0 :                   s% retry_message = 'bad num for w'
    1211            0 :                   ierr = -1
    1212            0 :                   if (s% stop_for_bad_nums) then
    1213            0 :                      write(*,2) 'set_vars_for_solver w', k, s% w(k)
    1214            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1215              :                   end if
    1216            0 :                   if (report) write(*,2) 'bad num w', k, s% w(k)
    1217              :                end if
    1218            0 :                s% Hp_face(k) = x(i_Hp)
    1219            0 :                if (is_bad_num(s% Hp_face(k))) then
    1220            0 :                   s% retry_message = 'bad num for Hp_face'
    1221            0 :                   ierr = -1
    1222            0 :                   if (s% stop_for_bad_nums) then
    1223            0 :                      write(*,2) 'set_vars_for_solver Hp_face', k, s% Hp_face(k)
    1224            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1225              :                   end if
    1226            0 :                   if (report) write(*,2) 'bad num Hp_face', k, s% Hp_face(k)
    1227              :                end if
    1228              :             end if
    1229              : 
    1230        39261 :             if (do_v) then
    1231            0 :                s% v(k) = x(i_v)
    1232            0 :                s% dxh_v(k) = s% solver_dx(i_v,k)
    1233            0 :                if (is_bad_num(s% v(k))) then
    1234            0 :                   s% retry_message = 'bad num for v'
    1235            0 :                   if (s% stop_for_bad_nums) then
    1236            0 :                      write(*,2) 'set_vars_for_solver v', k, s% v(k)
    1237            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1238              :                   end if
    1239            0 :                   if (report) write(*,2) 'bad num v', k, s% v(k)
    1240            0 :                   ierr = -1
    1241              :                end if
    1242              :             end if
    1243              : 
    1244        39261 :             if (do_u) then
    1245            0 :                s% u(k) = x(i_u)
    1246            0 :                s% dxh_u(k) = s% solver_dx(i_u,k)
    1247            0 :                if (is_bad_num(s% u(k))) then
    1248            0 :                   s% retry_message = 'bad num for u'
    1249            0 :                   if (s% stop_for_bad_nums) then
    1250            0 :                      write(*,2) 'set_vars_for_solver u', k, s% u(k)
    1251            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1252              :                   end if
    1253            0 :                   if (report) write(*,2) 'bad num u', k, s% u(k)
    1254            0 :                   ierr = -1
    1255              :                end if
    1256              :             end if
    1257              : 
    1258        39261 :             if (do_alpha_RTI) then
    1259            0 :                s% alpha_RTI(k) = max(0d0, x(i_alpha_RTI))
    1260            0 :                s% dxh_alpha_RTI(k) = s% solver_dx(i_alpha_RTI,k)
    1261            0 :                if (is_bad_num(s% alpha_RTI(k))) then
    1262            0 :                   s% retry_message = 'bad num for alpha_RTI'
    1263            0 :                   if (s% stop_for_bad_nums) then
    1264            0 :                      write(*,2) 'set_vars_for_solver alpha_RTI', k, s% alpha_RTI(k)
    1265            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1266              :                   end if
    1267            0 :                   if (report) write(*,2) 'bad num alpha_RTI', k, s% alpha_RTI(k)
    1268            0 :                   ierr = -1
    1269              :                end if
    1270            0 :                if (s% alpha_RTI(k) < 0d0) then
    1271            0 :                   s% alpha_RTI(k) = 0d0
    1272            0 :                   x(i_alpha_RTI) = 0d0
    1273              :                end if
    1274              :             end if
    1275              : 
    1276        39261 :             if (do_w_div_wc) then
    1277            0 :                s% w_div_w_crit_roche(k) = x(i_w_div_wc)
    1278            0 :                if (s% w_div_w_crit_roche(k) > 0.99d0) then
    1279            0 :                   s% w_div_w_crit_roche(k) = 0.99d0
    1280              :                end if
    1281            0 :                if (s% w_div_w_crit_roche(k) < -0.99d0) then
    1282            0 :                   s% w_div_w_crit_roche(k) = -0.99d0
    1283              :                end if
    1284            0 :                if (is_bad_num(s% w_div_w_crit_roche(k))) then
    1285            0 :                   s% retry_message = 'bad num for w_div_w_crit_roche'
    1286            0 :                   if (s% stop_for_bad_nums) then
    1287            0 :                      write(*,2) 'set_vars_for_solver w_div_w_crit_roche', k, s% w_div_w_crit_roche(k)
    1288            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1289              :                   end if
    1290            0 :                   if (report) write(*,2) 'bad num w_div_w_crit_roche', k, s% w_div_w_crit_roche(k)
    1291            0 :                   ierr = -1
    1292              :                end if
    1293              :             end if
    1294              : 
    1295        39261 :             if (do_j_rot) then
    1296            0 :                s% j_rot(k) = x(i_j_rot)
    1297            0 :                if (is_bad_num(s% j_rot(k))) then
    1298            0 :                   s% retry_message = 'bad num for j_rot'
    1299            0 :                   if (s% stop_for_bad_nums) then
    1300            0 :                      write(*,2) 'set_vars_for_solver j_rot', k, s% j_rot(k)
    1301            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1302              :                   end if
    1303            0 :                   if (report) write(*,2) 'bad num j_rot', k, s% j_rot(k)
    1304            0 :                   ierr = -1
    1305              :                end if
    1306              :             end if
    1307              : 
    1308        39261 :             if (do_lnR) then
    1309        39261 :                s% lnR(k) = x(i_lnR)
    1310        39261 :                s% r(k) = exp(s% lnR(k))
    1311        39261 :                s% dxh_lnR(k) = s% solver_dx(i_lnR,k)
    1312        39261 :                if (is_bad_num(s% lnR(k))) then
    1313            0 :                   s% retry_message = 'bad num for lnR'
    1314            0 :                   if (s% stop_for_bad_nums) then
    1315            0 :                      write(*,2) 'set_vars_for_solver r lnR solver_dx', &
    1316            0 :                         k, s% r(k), s% lnR(k), s% solver_dx(i_lnR,k)
    1317            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1318              :                   end if
    1319            0 :                   if (report) write(*,2) 'bad num r lnR solver_dx', &
    1320            0 :                      k, s% r(k), s% lnR(k), s% solver_dx(i_lnR,k)
    1321            0 :                   ierr = -1
    1322              :                end if
    1323              :             end if
    1324              : 
    1325        39261 :             if (do_lnd) then
    1326        39261 :                s% lnd(k) = x(i_lnd)
    1327        39261 :                s% rho(k) = exp(s% lnd(k))
    1328        39261 :                s% dxh_lnd(k) = s% solver_dx(i_lnd,k)
    1329        39261 :                if (s% lnd(k) < ln10*s% hydro_mtx_min_allowed_logRho) then
    1330            0 :                   write(s% retry_message, *) 'logRho < hydro_mtx_min_allowed_logRho', k
    1331            0 :                   if (report) &
    1332            0 :                      write(*,4) 'hydro_mtx: logRho too small', &
    1333            0 :                         s% model_number, k, s% solver_iter, &
    1334            0 :                         s% lnd(k)/ln10, s% lnd_start(k)/ln10
    1335            0 :                   ierr = -1
    1336            0 :                   return
    1337              :                end if
    1338        39261 :                if (s% lnd(k) > ln10*s% hydro_mtx_max_allowed_logRho .and. &
    1339              :                     s% min_logT_for_hydro_mtx_max_allowed < &
    1340              :                      ln10*min(s% lnT(k),s% lnT_start(k))) then
    1341            0 :                   write(s% retry_message, *) 'logRho > hydro_mtx_max_allowed_logRho', k
    1342            0 :                   if (s% report_ierr .or. report) &
    1343            0 :                      write(*,4) 'hydro_mtx: logRho too large', &
    1344            0 :                         s% model_number, k, s% solver_iter, &
    1345            0 :                         s% lnd(k)/ln10, s% lnd_start(k)/ln10
    1346            0 :                   ierr = -1
    1347            0 :                   return
    1348              :                end if
    1349              :                if (abs(s% lnd(k) - s% lnd_start(k)) > &
    1350        39261 :                      ln10*s% hydro_mtx_max_allowed_abs_dlogRho .and. &
    1351              :                     s% min_logT_for_hydro_mtx_max_allowed < &
    1352              :                      ln10*min(s% lnT(k),s% lnT_start(k))) then
    1353            0 :                   write(s% retry_message, *) 'abs(dlogRho) > hydro_mtx_max_allowed_abs_dlogRho', k
    1354            0 :                   if (s% report_ierr .or. report) &
    1355              :                      write(*,4) &
    1356            0 :                         'hydro_mtx: dlogRho, logRho, logRho_start', &
    1357            0 :                         s% model_number, k, s% solver_iter, &
    1358            0 :                         (s% lnd(k) - s% lnd_start(k))/ln10, &
    1359            0 :                         s% lnd(k)/ln10, s% lnd_start(k)/ln10
    1360            0 :                   ierr = -1
    1361            0 :                   return
    1362              :                end if
    1363        39261 :                if (is_bad_num(s% rho(k))) then
    1364            0 :                   write(s% retry_message, *) 'bad num for rho', k
    1365            0 :                   if (s% stop_for_bad_nums) then
    1366            0 :                      write(*,2) 'set_vars_for_solver rho', k, s% rho(k)
    1367            0 :                      call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1368              :                   end if
    1369            0 :                   if (report) write(*,2) 'bad num rho', k, s% rho(k)
    1370            0 :                   ierr = -1
    1371              :                end if
    1372              :             end if
    1373              : 
    1374        39261 :             if (do_chem) &
    1375              :                call check1_chem( &
    1376        39261 :                   s, k, min_xa_hard_limit, sum_xa_hard_limit, report, ierr)
    1377              : 
    1378        39294 :          end subroutine set1
    1379              : 
    1380              : 
    1381              :       end subroutine set_vars_for_solver
    1382              : 
    1383              : 
    1384        39261 :       subroutine check1_chem( &
    1385              :             s, k, min_xa_hard_limit, sum_xa_hard_limit, report, ierr)
    1386              :          use chem_def, only: chem_isos
    1387              :          type (star_info), pointer :: s
    1388              :          integer, intent(in) :: k
    1389              :          real(dp), intent(in) :: min_xa_hard_limit, sum_xa_hard_limit
    1390              :          logical, intent(in) :: report
    1391              :          integer, intent(out) :: ierr
    1392              : 
    1393              :          integer :: j, species
    1394        39261 :          real(dp) :: sum_xa
    1395              :          logical :: okay
    1396              : 
    1397              :          include 'formats'
    1398              : 
    1399        39261 :          ierr = 0
    1400        39261 :          species = s% species
    1401        39261 :          okay = .true.
    1402        39261 :          if (min_xa_hard_limit > -1d50) then
    1403       353349 :             do j=1,species
    1404       353349 :                if (s% xa(j,k) < min_xa_hard_limit) then
    1405            0 :                   s% retry_message = 'some xa < min_xa_hard_limit'
    1406            0 :                   if (report .or. s% report_bad_negative_xa) then
    1407              :                      write(*,3) &
    1408              :                         'bad negative xa, min_xa_hard_limit, sig, logT ' // &
    1409            0 :                         trim(chem_isos% name(s% chem_id(j))), j, k, &
    1410            0 :                         s% xa(j,k), min_xa_hard_limit, s% sig(k), s% lnT(k)/ln10
    1411            0 :                      okay = .false.
    1412              :                   end if
    1413            0 :                   ierr = -1
    1414            0 : !$omp critical (hydro_mtx_crit1)
    1415            0 :                   s% why_Tlim = Tlim_neg_X
    1416              : !$omp end critical (hydro_mtx_crit1)
    1417            0 :                   if (.not. report) return
    1418              :                end if
    1419              :             end do
    1420              :          end if
    1421              : 
    1422       353349 :          do j=1,species
    1423       353349 :             s% xa(j,k) = max(0d0, min(1d0, s% xa(j,k)))
    1424              :          end do
    1425              : 
    1426       353349 :          sum_xa = sum(s% xa(1:species,k))
    1427        39261 :          if (is_bad_num(sum_xa)) then
    1428            0 :             ierr = -1
    1429            0 :             s% retry_message = 'bad num for mass fractions'
    1430            0 :             if (s% stop_for_bad_nums) then
    1431            0 :                write(*,2) 'set_vars_for_solver sum_xa', k, sum_xa
    1432            0 :                call mesa_error(__FILE__,__LINE__,'set_vars_for_solver')
    1433              :             end if
    1434            0 :             if (report) then
    1435            0 :                write(*,'(a60,i8,99f20.10)') 'bad num sum X', k, s% m(k)/Msun, sum_xa
    1436              :             end if
    1437            0 : !$omp critical (hydro_mtx_crit2)
    1438            0 :             if (s% why_Tlim /= Tlim_neg_X) s% why_Tlim = Tlim_bad_Xsum
    1439              : !$omp end critical (hydro_mtx_crit2)
    1440            0 :             if (.not. report) return
    1441              :          end if
    1442        39261 :          if (abs(sum_xa - 1d0) > sum_xa_hard_limit) then
    1443            0 :             s% retry_message = 'mass fractions > sum_xa_hard_limit'
    1444            0 :             if (report) then
    1445              :                write(*,2) &
    1446            0 :                   'bad sumX', k, &
    1447            0 :                   sum_xa - 1d0, sum_xa_hard_limit, &
    1448            0 :                   sum(s% xa_start(1:species,k)), &
    1449            0 :                   sum_xa - sum(s% xa_start(1:species,k))
    1450              :             end if
    1451            0 :             ierr = -1
    1452            0 : !$omp critical (hydro_mtx_crit3)
    1453            0 :             if (s% why_Tlim /= Tlim_neg_X) s% why_Tlim = Tlim_bad_Xsum
    1454              : !$omp end critical (hydro_mtx_crit3)
    1455            0 :             okay = .false.
    1456            0 :             if (.not. report) return
    1457              :          end if
    1458              : 
    1459        39261 :          if (abs(sum_xa - 1d0) > 1d-12) then
    1460              :             !jmax = maxloc(s% xa(1:species,k),dim=1)
    1461              :             !xsum = sum(s% xa(1:species,k)) - s% xa(jmax,k)
    1462              :             !if (1d0 > xsum) then
    1463              :             !   s% xa(jmax,k) = 1d0 - xsum
    1464              :             !else
    1465         5598 :                do j=1,species
    1466         5598 :                   s% xa(j,k) = s% xa(j,k)/sum_xa
    1467              :                end do
    1468              :             !end if
    1469              :          end if
    1470              : 
    1471        39261 :          if (s% xa_clip_limit > 0) then
    1472       353349 :             do j=1,species
    1473       353349 :                if (s% xa(j,k) < s% xa_clip_limit) s% xa(j,k) = 0d0
    1474              :             end do
    1475              :          end if
    1476              : 
    1477        39261 :       end subroutine check1_chem
    1478              : 
    1479              : 
    1480              :       subroutine dump_struct(s)
    1481              :          type (star_info), pointer :: s
    1482              :          integer :: k, j
    1483              : 
    1484              :          include 'formats'
    1485              : 
    1486              :          do k=1,s% nz
    1487              :             write(*,2) 'dq', k, s% dq(k)
    1488              :             write(*,2) 'm', k, s% m(k)
    1489              :             write(*,2) 'T', k, s% T(k)
    1490              :             write(*,2) 'rho', k, s% rho(k)
    1491              :             write(*,2) 'Pgas', k, s% Pgas(k)
    1492              :             write(*,2) 'L', k, s% L(k)
    1493              :             write(*,2) 'r', k, s% r(k)
    1494              :             write(*,2) 'grada', k, s% grada(k)
    1495              :             write(*,2) 'opacity', k, s% opacity(k)
    1496              :             write(*,2) 'd_opacity_dlnd', k, s% d_opacity_dlnd(k)
    1497              :             write(*,2) 'd_opacity_dlnT', k, s% d_opacity_dlnT(k)
    1498              :             write(*,2) 'eps_nuc', k, s% eps_nuc(k)
    1499              :             write(*,2) 'd_epsnuc_dlnd', k, s% d_epsnuc_dlnd(k)
    1500              :             write(*,2) 'd_epsnuc_dlnT', k, s% d_epsnuc_dlnT(k)
    1501              :             write(*,2) 'non_nuc_neu', k, s% non_nuc_neu(k)
    1502              :             write(*,2) 'd_nonnucneu_dlnd', k, s% d_nonnucneu_dlnd(k)
    1503              :             write(*,2) 'd_nonnucneu_dlnT', k, s% d_nonnucneu_dlnT(k)
    1504              :             write(*,2) 'eps_grav', k, s% eps_grav_ad(k)% val
    1505              :             write(*,2) 'gradT', k, s% gradT(k)
    1506              :             !write(*,2) '', k, s% (k)
    1507              :             do j=1,s% species
    1508              :                write(*,3) 'xa(j,k)', j, k, s% xa(j,k)
    1509              :             end do
    1510              :          end do
    1511              : 
    1512              : 
    1513        39261 :       end subroutine dump_struct
    1514              : 
    1515              : 
    1516           33 :       subroutine edit_lnR(s, xh_start, dx)
    1517              :          ! uses mass and density to set radius
    1518              :          type (star_info), pointer :: s
    1519              :          real(dp), dimension(:, :) :: xh_start
    1520              :          real(dp), dimension(:, :) :: dx
    1521           33 :          real(dp) :: vol00, volp1, cell_vol
    1522              :          integer :: k, nz
    1523              :          include 'formats'
    1524           33 :          vol00 = four_thirds_pi*s% R_center*s% R_center*s% R_center
    1525           33 :          nz = s% nz
    1526        39294 :          do k=nz, 1, -1
    1527        39261 :             volp1 = vol00
    1528        39261 :             cell_vol = s% dm(k)/s% rho(k)
    1529        39261 :             vol00 = volp1 + cell_vol
    1530        39261 :             s% lnR(k) = log(vol00/four_thirds_pi)/3
    1531        39294 :             dx(s% i_lnR,k) = s% lnR(k) - xh_start(s% i_lnR,k)
    1532              :          end do
    1533           33 :          call edit_dlnR_dt_above_k_below_just_added(s, xh_start)
    1534           33 :       end subroutine edit_lnR
    1535              : 
    1536              : 
    1537           33 :       subroutine edit_dlnR_dt_above_k_below_just_added(s, xh_start)
    1538              :          type (star_info), pointer :: s
    1539              :          real(dp), dimension(:, :) :: xh_start
    1540              :          integer :: k_below_just_added
    1541              :          real(dp) :: lnR_start
    1542           33 :          k_below_just_added = s% k_below_just_added
    1543              :          if (k_below_just_added == 1) return
    1544              :          lnR_start = xh_start(s% i_lnR,1)
    1545              :       end subroutine edit_dlnR_dt_above_k_below_just_added
    1546              : 
    1547              :       end module solver_support
        

Generated by: LCOV version 2.0-1