LCOV - code coverage report
Current view: top level - star/private - mesh_adjust.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 37.0 % 1252 463
Test Date: 2025-05-08 18:23:42 Functions: 51.6 % 31 16

            Line data    Source code
       1              :  ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2019  The MESA Team
       4              : !
       5              : !   This program is free software: you can redistribute it and/or modify
       6              : !   it under the terms of the GNU Lesser General Public License
       7              : !   as published by the Free Software Foundation,
       8              : !   either version 3 of the License, or (at your option) any later version.
       9              : !
      10              : !   This program is distributed in the hope that it will be useful,
      11              : !   but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              : !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13              : !   See the GNU Lesser General Public License for more details.
      14              : !
      15              : !   You should have received a copy of the GNU Lesser General Public License
      16              : !   along with this program. If not, see <https://www.gnu.org/licenses/>.
      17              : !
      18              : ! ***********************************************************************
      19              : 
      20              :       module mesh_adjust
      21              : 
      22              :       use const_def, only: dp, ln10, one_third, four_thirds_pi
      23              :       use star_private_def
      24              :       use chem_def
      25              :       use interp_1d_def, only: pm_work_size
      26              :       use utils_lib
      27              :       use star_utils, only: get_r_from_xh, store_r_in_xh, store_rho_in_xh, &
      28              :          get_lnT_from_xh, store_lnT_in_xh, store_lnd_in_xh
      29              : 
      30              :       implicit none
      31              : 
      32              :       private
      33              :       public :: do_mesh_adjust, do_prune_mesh_surface, &
      34              :          set_lnT_for_energy_with_tol, set_lnT_for_energy
      35              : 
      36              :       integer, parameter :: nwork = pm_work_size
      37              : 
      38              :       real(dp), parameter :: eta_limit = -1d-6
      39              : 
      40              : 
      41              :       logical, parameter :: dbg = .false.
      42              : 
      43              :       contains
      44              : 
      45           10 :       subroutine do_mesh_adjust( &
      46              :             s, nz, nz_old, xh_old, xa_old, &
      47              :             energy_old, eta_old, lnd_old, lnPgas_old, &
      48              :             j_rot_old, i_rot_old, omega_old, D_omega_old, &
      49              :             mlt_vc_old, lnT_old, w_old, specific_PE_old, specific_KE_old, &
      50              :             old_m, old_r, old_rho, dPdr_dRhodr_info_old, D_mix_old, &
      51           10 :             cell_type, comes_from, dq_old, xq_old, xh, xa, dq, xq, ierr)
      52              :          use chem_lib, only: basic_composition_info
      53              :          use interp_1d_def
      54              :          use interp_1d_lib
      55              :          use star_utils, only: set_m_grav_and_grav
      56              :          use auto_diff_support
      57              :          type (star_info), pointer :: s
      58              :          integer, intent(in) :: nz, nz_old
      59              :          integer, dimension(:) :: cell_type, comes_from
      60              :          real(dp), dimension(:), pointer :: &
      61              :             dq_old, xq_old, dq, xq, energy_old, eta_old, &
      62              :             lnd_old, lnPgas_old, mlt_vc_old, lnT_old, w_old, &
      63              :             specific_PE_old, specific_KE_old, &
      64              :             old_m, old_r, old_rho, dPdr_dRhodr_info_old, &
      65              :             j_rot_old, omega_old, D_omega_old, D_mix_old
      66              :          type(auto_diff_real_star_order1), dimension(:), pointer :: i_rot_old
      67              :          real(dp), dimension(:,:), pointer :: xh_old, xa_old
      68              :          real(dp), dimension(:,:), pointer :: xh, xa
      69              :          integer, intent(out) :: ierr
      70              : 
      71           10 :          real(dp) :: dxa, xmstar, mstar, sumx, &
      72           10 :             total_internal_energy1, total_internal_energy2, err
      73              :          character (len=strlen) :: message
      74              :          integer :: k, j, op_err, nzlo, nzhi, nzlo_old, nzhi_old, species
      75           10 :          real(dp), pointer :: work(:)
      76              :          real(dp), dimension(:), allocatable :: &
      77           10 :             dqbar, dqbar_old, new_r, Vol_new, xq_old_plus1, &
      78           10 :             xout_old, xout_new, xq_new, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, &
      79           10 :             energy_new, density_new
      80           10 :          real(dp), dimension(:,:), allocatable :: xa_c0, xa_c1, xa_c2
      81              : 
      82              :          include 'formats'
      83              : 
      84           10 :          ierr = 0
      85           10 :          species = s% species
      86              : 
      87           10 :          xmstar = s% xmstar
      88           10 :          mstar = xmstar + s% M_center
      89              : 
      90              :          ! check xq's
      91        10633 :          do k=1,nz
      92        10633 :             if (xq(k) < 0 .or. xq(k) > 1) then
      93            0 :                ierr = -1
      94            0 :                return
      95              : 
      96              :                write(*,*) 'k', k
      97              :                write(*,*) 'xq(k)', xq(k)
      98              :                call mesa_error(__FILE__,__LINE__,'debug: do_mesh_adjust')
      99              :             end if
     100              :          end do
     101              : 
     102              :          if (dbg) write(*,*) 'enter do_mesh_adjust'
     103              : 
     104           10 :          nzlo = 0
     105         8446 :          do k = 1, nz
     106         8446 :             if (cell_type(k) /= unchanged_type) then
     107              :                if (dbg) write(*,2) 'nzlo changed', k
     108            4 :                nzlo = k; exit
     109              :             end if
     110              :          end do
     111           10 :          if (nzlo == 0) then
     112              :             if (dbg) write(*,2) 'no cells changed'
     113            6 :             nzlo = nz
     114              :          end if
     115              : 
     116           10 :          nzhi = nzlo
     117          252 :          do k = nz, nzlo, -1
     118          252 :             if (cell_type(k) /= unchanged_type) then
     119              :                if (dbg) write(*,2) 'nzhi changed', k
     120            4 :                nzhi = k; exit
     121              :             end if
     122              :          end do
     123              : 
     124              :          ! extend range for purposes of interpolation
     125           10 :          if (nzhi < nz) nzhi = nzhi+1
     126           10 :          if (nzlo > 1) nzlo = nzlo-1
     127              : 
     128           10 :          nzlo_old = comes_from(nzlo)
     129           10 :          if (nzhi == nz) then
     130            6 :             nzhi_old = nz_old
     131              :          else
     132            4 :             nzhi_old = comes_from(nzhi+1)
     133              :          end if
     134              : 
     135           10 :          call do_alloc(ierr)
     136           10 :          if (ierr /= 0) return
     137              : 
     138        10613 :          do k=2,nz-1
     139        10613 :             dqbar(k) = 0.5d0*(dq(k-1) + dq(k))
     140              :          end do
     141           10 :          dqbar(1) = 0.5d0*dq(1)
     142           10 :          dqbar(nz) = 0.5d0*dq(nz-1) + dq(nz)
     143              : 
     144        12085 :          do k=2,nz_old-1
     145        12085 :             dqbar_old(k) = 0.5d0*(dq_old(k-1) + dq_old(k))
     146              :          end do
     147           10 :          dqbar_old(1) = 0.5d0*dq_old(1)
     148           10 :          dqbar_old(nz_old) = 0.5d0*dq_old(nz_old-1) + dq_old(nz_old)
     149              : 
     150        12105 :          do k=1,nz_old
     151        12105 :             xq_old_plus1(k) = xq_old(k)
     152              :          end do
     153              :          ! add point at true center so can interpolate xq_new > xq_old(nz_old)
     154           10 :          xq_old_plus1(nz_old+1) = 1
     155              : 
     156         1981 :          do k = 1, nzhi - nzlo + 1
     157         1981 :             xq_new(k) = xq(nzlo+k-1)
     158              :          end do
     159              : 
     160           10 :          xout_old(1) = xq_old(1)
     161        12095 :          do k=2,nz_old
     162        12095 :             xout_old(k) = xout_old(k-1) + dqbar_old(k-1)
     163              :          end do
     164              : 
     165           10 :          xout_new(1) = xq(1)
     166        10623 :          do k=2,nz
     167        10623 :             xout_new(k) = xout_new(k-1) + dqbar(k-1)
     168              :          end do
     169              : 
     170              :          if (dbg) write(*,*) 'call do_L'
     171              :          call do_L( &
     172              :             s, nz, nz_old, nzlo, nzhi, comes_from, &
     173              :             xh, xh_old, xq, xq_old_plus1, xq_new, &
     174           10 :             work, tmp1, tmp2, ierr)
     175            0 :          if (failed('do_L')) return
     176              : 
     177           10 :          if (s% RTI_flag) then
     178              :             if (dbg) write(*,*) 'call do_alpha_RTI'
     179              :             call do_alpha_RTI( &
     180              :                s, nz, nz_old, nzlo, nzhi, comes_from, &
     181              :                xh, xh_old, xq, xq_old_plus1, xq_new, &
     182            0 :                work, tmp1, tmp2, ierr)
     183            0 :             if (failed('do_alpha_RTI')) return
     184              :             call do_interp_pt_val( &
     185              :                s, nz, nz_old, nzlo, nzhi, s% dPdr_dRhodr_info, dPdr_dRhodr_info_old, &
     186            0 :                0d0, xq, xq_old_plus1, xq_new, .true., work, tmp1, tmp2, ierr)
     187            0 :             if (failed('dPdr_dRhodr_info')) return
     188              :          end if
     189              : 
     190              :          if (dbg) write(*,*) 'call do_lnR_and_lnd'
     191              :          call do_lnR_and_lnd( &
     192              :             s, nz, nz_old, nzlo, nzhi, cell_type, comes_from, &
     193              :             xh, xh_old, xmstar, lnd_old, lnPgas_old, &
     194              :             dqbar, dqbar_old, old_r, old_m, old_rho, &
     195              :             dq, dq_old, xq, xq_old_plus1, density_new, work, &
     196           10 :             tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, ierr)
     197            0 :          if (failed('do_lnR_and_lnd')) return
     198              : 
     199           10 :          if (s% v_flag) then  ! calculate new v to conserve kinetic energy
     200              :             if (dbg) write(*,*) 'call do_v'
     201              :             call do_v( &
     202              :                s, nz, nz_old, cell_type, comes_from, &
     203              :                xq_old, xq, dq_old, dq, xh, xh_old, &
     204            0 :                xout_old, xout_new, dqbar_old, dqbar, tmp1, ierr)
     205            0 :             if (failed('do_v')) return
     206              :          end if
     207              : 
     208           10 :          if (s% u_flag) then  ! calculate new u to conserve kinetic energy
     209              :             if (dbg) write(*,*) 'call do_u'
     210              :             call do_u( &
     211              :                s, nz, nz_old, cell_type, comes_from, &
     212              :                xq_old, xq, dq_old, dq, xh, xh_old, &
     213            0 :                xout_old, xout_new, tmp1, ierr)
     214            0 :             if (failed('do_u')) return
     215              :          end if
     216              : 
     217           10 :          if (s% RSP2_flag) then  ! calculate new etrb to conserve turbulent energy
     218              :             if (dbg) write(*,*) 'call do_etrb'
     219              :             call do_etrb( &
     220              :                s, nz, nz_old, cell_type, comes_from, &
     221              :                xq_old, xq, dq_old, dq, xh, xh_old, &
     222            0 :                xout_old, xout_new, tmp1, ierr)
     223            0 :             if (failed('do_etrb')) return
     224              :             if (dbg) write(*,*) 'call do_Hp_face'
     225              :             call do_Hp_face( &
     226              :                s, nz, nz_old, nzlo, nzhi, comes_from, &
     227              :                xh, xh_old, xq, xq_old_plus1, xq_new, &
     228            0 :                work, tmp1, tmp2, ierr)
     229            0 :             if (failed('do_Hp_face')) return
     230              :          end if
     231              : 
     232           10 :          if (s% rotation_flag) then
     233              :             call adjust_omega(s, nz, nz_old, comes_from, &
     234              :                xq_old, xq, dq_old, dq, xh, j_rot_old, &
     235            0 :                xout_old, xout_new, dqbar_old, dqbar, ierr)
     236            0 :             if (failed('adjust_omega')) return
     237            0 :             if (s% D_omega_flag) then
     238              :                call do_interp_pt_val( &
     239              :                   s, nz, nz_old, nzlo, nzhi, s% D_omega, D_omega_old, &
     240            0 :                   0d0, xq, xq_old_plus1, xq_new, .true., work, tmp1, tmp2, ierr)
     241            0 :                if (failed('D_omega')) return
     242              :             end if
     243              :          end if
     244              : 
     245              :          call do_interp_pt_val( &
     246              :             s, nz, nz_old, nzlo, nzhi, s% mlt_vc, mlt_vc_old, &
     247           20 :             0d0, xq, xq_old_plus1, xq_new, .true., work, tmp1, tmp2, ierr)
     248            0 :          if (failed('mlt_cv')) return
     249              : 
     250              :          call do_interp_pt_val( &
     251              :             s, nz, nz_old, nzlo, nzhi, s% D_mix, D_mix_old, &
     252           20 :             0d0, xq, xq_old_plus1, xq_new, .true., work, tmp1, tmp2, ierr)
     253            0 :          if (failed('D_mix')) return
     254              : 
     255         3457 :          do k=nzlo_old,nzhi_old  ! 1,nz_old  !
     256              : 
     257              :             ! since we must adjust things to make the sum of xa's = 1,
     258              :             ! only do linear reconstruction.
     259        31023 :             do j=1,species
     260              :                call get1_lpp(k, species, nz_old, j, dq_old, xa_old, &
     261        31023 :                               .false., xa_c0(:,j), xa_c1(:,j), xa_c2(:,j))
     262              :             end do
     263              : 
     264        31023 :             sumx = sum(xa_old(1:species,k))
     265        31023 :             do j=1,species
     266        27576 :                xa_c0(k,j) = xa_old(j,k)/sumx  ! make sure that adds to 1
     267        31023 :                xa_c2(k,j) = 0  ! no curvature terms
     268              :             end do
     269              : 
     270              :             ! only reduce magnitude of slopes
     271              :             ! so don't risk producing values out of [0..1] range
     272        31023 :             if (sum(xa_c1(k,:)) > 0) then
     273        14085 :                j = maxloc(xa_c1(k,:), dim=1)
     274              :             else
     275        16938 :                j = minloc(xa_c1(k,:), dim=1)
     276              :             end if
     277         3447 :             xa_c1(k,j) = 0
     278        31023 :             xa_c1(k,j) = -sum(xa_c1(k,:))
     279              :             ! check for valid fractions at boundaries; set slopes to 0 if find a bad one.
     280        31033 :             do j=1,species
     281        27576 :                dxa = abs(xa_c1(k,j))*dq_old(k)/2
     282        31023 :                if (xa_c0(k,j) + dxa > 1 .or. xa_c0(k,j) - dxa < 0) then
     283            0 :                   xa_c1(k,:) = 0
     284              :                   exit
     285              :                end if
     286              :             end do
     287              : 
     288              :          end do
     289              : 
     290            0 :          if (failed('adjust_mesh nz_old parallel loop')) return
     291              : 
     292              :          if (dbg) write(*,*) 'do xa and lnT'
     293              : 
     294              :          total_internal_energy1 = &
     295        12105 :             dot_product(dq_old(1:nz_old), energy_old(1:nz_old))
     296              : 
     297        10633 :          do k = 1, nz
     298              : 
     299              :             op_err = 0
     300              : 
     301              :             ! calculate new abundances to conserve species
     302              :             call do_xa( &
     303              :                s, nz, nz_old, k, species, cell_type, comes_from, xa, xa_old, &
     304              :                xa_c0, xa_c1, xa_c2, xq, dq, xq_old, dq_old, &
     305        10623 :                .true., op_err)
     306        10633 :             if (op_err /= 0) then
     307            0 :                write(*,2) 'failed for do_xa', k
     308            0 :                stop
     309              :                write(message,*) 'do_xa for k', k
     310              :                ierr = op_err
     311              :             end if
     312              : 
     313              :          end do
     314              : 
     315              :          ! ensure the things we need to calculate m_grav and grav are up to date
     316        10633 :          do k = 1, nz
     317              : 
     318        10623 :             op_err = 0
     319              : 
     320              :             ! ensure that mass corrections are up to date
     321              :             call basic_composition_info( &
     322              :                  species, s% chem_id, xa(1:species,k), s% X(k), s% Y(k), s% Z(k), &
     323              :                  s% abar(k), s% zbar(k), s% z2bar(k), s% z53bar(k), &
     324        10623 :                  s% ye(k), s% mass_correction(k), sumx)
     325              : 
     326              :             ! ensure that r is up to date
     327        10633 :             s% r(k) = exp(s% xh(s% i_lnr,k))
     328              : 
     329              :          end do
     330              : 
     331              :          ! needed because do1_lnT evaluates PE
     332           10 :          call set_m_grav_and_grav(s)
     333              : 
     334        10633 :          do k = 1, nz
     335              : 
     336              :             op_err = 0
     337              : 
     338              :             ! calculate new temperatures to conserve energy
     339              :             call do1_lnT( &
     340              :                s, nz_old, k, species, cell_type, comes_from, &
     341              :                xa, xh, xh_old, &
     342              :                xq, dq, xq_old, dq_old, eta_old, energy_old, lnT_old, &
     343              :                specific_PE_old, specific_KE_old, w_old, &
     344        10623 :                density_new, energy_new, op_err)
     345        10623 :             if (op_err /= 0) then
     346            0 :                write(*,2) 'failed for do1_lnT', k
     347            0 :                stop
     348              :                write(message,*) 'do1_lnT for k', k
     349              :                ierr = op_err
     350              :             end if
     351        10633 :             if (is_bad(energy_new(k)) .or. is_bad(dq(k))) then
     352            0 :                write(*,2) 'energy_new', k, energy_new(k)
     353            0 :                write(*,2) 'dq', k, dq(k)
     354            0 :                stop ''
     355              :             end if
     356              : 
     357              :          end do
     358              : 
     359            0 :          if (failed(message)) return
     360              : 
     361        10633 :          total_internal_energy2 = dot_product(dq(1:nz), energy_new(1:nz))
     362              :          err = abs(total_internal_energy1 - total_internal_energy2)/ &
     363           10 :                max(abs(total_internal_energy1),abs(total_internal_energy2),1d0)
     364           10 :          s% mesh_adjust_IE_conservation = err
     365              : 
     366           10 :          if (s% trace_mesh_adjust_error_in_conservation) then
     367              : 
     368            0 :             write(*,2) 'mesh adjust error in conservation of IE', &
     369            0 :                s% model_number, err, total_internal_energy2, total_internal_energy1
     370            0 :             if (err > 1d-8) then
     371            0 :                call show_errors
     372            0 :                write(*,*) 'err too large'
     373            0 :                call mesa_error(__FILE__,__LINE__,'mesh adjust')
     374              :             end if
     375              : 
     376              :          end if
     377              : 
     378              :          if (dbg) write(*,*) 'call check_species_conservation'
     379           10 :          call check_species_conservation(species,ierr)
     380           10 :          if (ierr /= 0) then
     381            0 :             write(*,*) 'failed in check_species_conservation'
     382            0 :             stop
     383              :          end if
     384              : 
     385           10 :          call dealloc
     386              : 
     387              :          contains
     388              : 
     389            0 :          subroutine show_errors
     390              :             integer :: k0, k0_from, k, k_from, k_outer
     391            0 :             real(dp) :: new_sum, old_sum
     392              : 
     393              :             include 'formats'
     394              : 
     395              :             k0 = 1
     396              :             k0_from = 1
     397            0 :             k_outer = 2
     398            0 :             write(*,'(A)')
     399              :             do
     400            0 :                if (cell_type(k_outer) == unchanged_type .and. k_outer /= nz) then
     401            0 :                   k_outer = k_outer + 1
     402            0 :                   cycle
     403              :                end if
     404            0 :                k0 = k_outer
     405            0 :                k0_from = comes_from(k_outer)
     406            0 :                do k = k0+1, nz
     407            0 :                   if (cell_type(k) /= unchanged_type .and. k /= nz) cycle
     408            0 :                   new_sum = dot_product(dq(k0:k),energy_new(k0:k))
     409            0 :                   k_from = comes_from(k)
     410              :                   old_sum = &
     411            0 :                      dot_product(dq_old(k0_from:k_from),energy_old(k0_from:k_from))
     412            0 :                   write(*,5) 'section err', k0, k, k0_from, k_from, &
     413            0 :                      abs(old_sum - new_sum)/max(abs(old_sum),abs(new_sum),1d0), &
     414            0 :                      old_sum, new_sum
     415            0 :                   k_outer = k
     416            0 :                   exit
     417              :                end do
     418            0 :                if (k_outer == nz) exit
     419            0 :                k_outer = k_outer + 1
     420              :             end do
     421            0 :             write(*,2) 'nz_old', nz_old
     422            0 :             write(*,2) 'nz', nz
     423            0 :             write(*,'(A)')
     424              : 
     425           10 :          end subroutine show_errors
     426              : 
     427           10 :          subroutine do_alloc(ierr)
     428              :             integer, intent(out) :: ierr
     429              :             integer :: sz
     430           10 :             sz = max(nz, nz_old) + 1
     431           10 :             call do_work_arrays(.true.,ierr)
     432              :             allocate( &
     433            0 :                dqbar(sz), dqbar_old(sz), new_r(sz), Vol_new(sz), xq_old_plus1(sz), &
     434            0 :                xout_old(sz), xout_new(sz), xq_new(sz), energy_new(sz), density_new(sz), &
     435            0 :                tmp1(sz), tmp2(sz), tmp3(sz), tmp4(sz), tmp5(sz), tmp6(sz), tmp7(sz), &
     436           20 :                xa_c0(sz,species), xa_c1(sz,species), xa_c2(sz,species))
     437           10 :          end subroutine do_alloc
     438              : 
     439           10 :          subroutine dealloc
     440           10 :             call do_work_arrays(.false.,ierr)
     441              :          end subroutine dealloc
     442              : 
     443           20 :          subroutine do_work_arrays(alloc_flag, ierr)
     444              :             use interp_1d_def
     445              :             use alloc
     446              :             logical, intent(in) :: alloc_flag
     447              :             integer, intent(out) :: ierr
     448              :             logical, parameter :: crit = .false.
     449              :             ierr = 0
     450              :             call work_array(s, alloc_flag, crit, &
     451           20 :                 work, (nz_old+1)*pm_work_size, nz_alloc_extra, 'mesh_adjust', ierr)
     452           20 :             if (ierr /= 0) return
     453           20 :          end subroutine do_work_arrays
     454              : 
     455              : 
     456           60 :          logical function failed(msg)
     457              :             character (len=*) :: msg
     458           60 :             if (ierr == 0) then
     459           60 :                failed = .false.
     460              :                return
     461              :             end if
     462            0 :             failed = .true.
     463              :             if (dbg) write(*, *) 'mesh_revisions failed in ' // trim(msg)
     464              :             call dealloc
     465              :             return
     466           20 :          end function failed
     467              : 
     468              : 
     469           10 :          subroutine check_species_conservation(species,ierr)
     470              :             integer, intent(in) :: species
     471              :             integer, intent(out) :: ierr
     472              :             integer :: j, k, jbad
     473           10 :             real(dp) :: old_total, new_total
     474              :             logical :: okay
     475              :             include 'formats'
     476           10 :             ierr = 0
     477           10 :             okay = .true.
     478           10 :             jbad = -1
     479           90 :             do j=1,species
     480        96840 :                old_total = dot_product(xa_old(j,1:nz_old),dq_old(1:nz_old))
     481           80 :                if (old_total < 1d-9) cycle
     482        85064 :                new_total = dot_product(xa(j,1:nz),dq(1:nz))
     483           90 :                if (abs(new_total - old_total) > 1d-4) then  ! check for major problems
     484            0 :                   ierr = -1
     485            0 :                   jbad = j
     486            0 :                   okay = .false.
     487              :                   if (dbg) then
     488              :                      write(*,*) 'problem with conservation of species ' //  &
     489              :                         chem_isos% name(s% chem_id(j))
     490              :                      write(*,1) 'new mass fraction', new_total
     491              :                      write(*,1) 'old mass fraction', old_total
     492              :                      write(*,1) 'new - old', new_total - old_total
     493              :                      write(*,1) '(new - old)/old', (new_total - old_total) / old_total
     494              :                      write(*,'(A)')
     495              :                   end if
     496              :                end if
     497              :             end do
     498           10 :             if (okay) return
     499            0 :             ierr = -1
     500            0 :             write(*,'(A)')
     501            0 :             do j=1,species
     502            0 :                old_total = dot_product(xa_old(j,1:nz_old),dq_old(1:nz_old))
     503            0 :                if (old_total < 1d-9) cycle
     504            0 :                new_total = dot_product(xa(j,1:nz),dq(1:nz))
     505            0 :                write(*,2) 'new - old mass fraction ' // chem_isos% name(s% chem_id(j)), &
     506            0 :                      j, new_total-old_total
     507              :             end do
     508            0 :             write(*,'(A)')
     509            0 :             j = jbad
     510            0 :             do k=2, nz
     511            0 :                if (comes_from(k) == comes_from(k-1)) cycle
     512            0 :                old_total = dot_product(xa_old(j,1:comes_from(k)-1),dq_old(1:comes_from(k)-1))
     513            0 :                if (old_total < 1d-9) cycle
     514            0 :                new_total = dot_product(xa(j,1:k-1),dq(1:k-1))
     515            0 :                write(*,2) 'partial new - old ' // chem_isos% name(s% chem_id(j)), k, &
     516            0 :                   new_total-old_total, new_total, old_total
     517              :             end do
     518            0 :             write(*,'(A)')
     519            0 :             do k=415, nz
     520            0 :                write(*,'(a30,99i6)') 'cell_type(k)', k, cell_type(k), comes_from(k)
     521              :             end do
     522            0 :             write(*,'(A)')
     523            0 :             write(*,2) 'xq', 439, xq(439)
     524            0 :             write(*,2) 'xq_old', 429, xq_old(429)
     525            0 :             write(*,2) 'dq_old', 429, dq_old(429)
     526            0 :             write(*,2) 'dq', 439, dq(439)
     527            0 :             write(*,'(A)')
     528            0 :             write(*,2) 'xq', 424, xq(424)
     529            0 :             write(*,2) 'xq_old', 428, xq_old(428)
     530            0 :             write(*,2) 'dq_old', 428, dq_old(428)
     531            0 :             write(*,2) 'sum dq', 424, sum(dq(424:438))
     532            0 :             write(*,'(A)')
     533            0 :             write(*,2) 'xq_old + dq_old', 428, xq_old(428) + dq_old(428)
     534            0 :             write(*,2) 'xq_old', 429, xq_old(429)
     535            0 :             write(*,'(A)')
     536            0 :             write(*,2) 'xq + sum dq', 424, xq(424) + sum(dq(424:438))
     537            0 :             write(*,2) 'xq', 439, xq(439)
     538            0 :             write(*,'(A)')
     539            0 :             write(*,1) 'sum dq_old', sum(dq_old(1:nz_old))
     540              : 
     541            0 :             write(*,2) 'dq_old', 427, dq_old(427)
     542            0 :             write(*,2) 'sum new', 416, sum(dq(416:423))
     543            0 :             write(*,2) 'dq_old - sum new', 427, dq_old(427) - sum(dq(416:423))
     544            0 :             write(*,2) 'dq_old', 428, dq_old(428)
     545            0 :             write(*,2) 'sum new', 424, sum(dq(424:438))
     546            0 :             write(*,2) 'dq_old - sum new', 428, dq_old(428) - sum(dq(424:438))
     547              :          end subroutine check_species_conservation
     548              : 
     549              : 
     550              :       end subroutine do_mesh_adjust
     551              : 
     552              : 
     553            0 :       subroutine do_prune_mesh_surface( &
     554              :             s, nz, nz_old, xh_old, xa_old, &
     555              :             j_rot_old, i_rot_old, omega_old, D_omega_old, am_nu_rot_old, &
     556              :             mlt_vc_old, lnT_old, &
     557              :             dPdr_dRhodr_info_old, nu_ST_old, D_ST_old, D_DSI_old, D_SH_old, &
     558              :             D_SSI_old, D_ES_old, D_GSF_old, D_mix_old, &
     559              :             xh, xa, ierr)
     560              :          use auto_diff_support
     561              :          type (star_info), pointer :: s
     562              :          integer, intent(in) :: nz, nz_old
     563              :          real(dp), dimension(:), pointer :: &
     564              :             j_rot_old, omega_old, &
     565              :             D_omega_old, am_nu_rot_old, mlt_vc_old, lnT_old, &
     566              :             dPdr_dRhodr_info_old, nu_ST_old, D_ST_old, D_DSI_old, D_SH_old, &
     567              :             D_SSI_old, D_ES_old, D_GSF_old, D_mix_old
     568              :          type(auto_diff_real_star_order1), dimension(:), pointer :: i_rot_old
     569              :          real(dp), dimension(:,:), pointer :: xh_old, xa_old
     570              :          real(dp), dimension(:,:), pointer :: xh, xa
     571              :          integer, intent(out) :: ierr
     572              : 
     573              :          integer :: skip, k, k_old, j
     574              : 
     575              :          include 'formats'
     576              : 
     577            0 :          ierr = 0
     578            0 :          skip = nz_old - nz
     579            0 :          if (skip < 0) then
     580            0 :             write(*,3) 'bad nz prune_surface do_prune_mesh_surface', nz_old, nz
     581            0 :             ierr = -1
     582              :             return
     583              :          end if
     584              : 
     585            0 :          do k = 1, nz
     586            0 :             k_old = k + skip
     587            0 :             do j = 1, s% nvar_hydro
     588            0 :                xh(j,k) = xh_old(j,k_old)
     589              :             end do
     590            0 :             do j = 1, s% species
     591            0 :                xa(j,k) = xa_old(j,k_old)
     592              :             end do
     593              :          end do
     594              : 
     595            0 :          call prune1(s% lnT, lnT_old, skip)
     596            0 :          call prune1(s% D_mix, D_mix_old, skip)
     597              : 
     598            0 :          if (s% rotation_flag) then
     599            0 :             call prune1(s% j_rot, j_rot_old, skip)
     600            0 :             call prune1_ad(s% i_rot, i_rot_old, skip)
     601            0 :             call prune1(s% omega, omega_old, skip)
     602            0 :             call prune1(s% nu_ST, nu_ST_old, skip)
     603            0 :             call prune1(s% D_ST, D_ST_old, skip)
     604            0 :             call prune1(s% D_DSI, D_DSI_old, skip)
     605            0 :             call prune1(s% D_SH, D_SH_old, skip)
     606            0 :             call prune1(s% D_SSI, D_SSI_old, skip)
     607            0 :             call prune1(s% D_ES, D_ES_old, skip)
     608            0 :             call prune1(s% D_GSF, D_GSF_old, skip)
     609              :          end if
     610              : 
     611            0 :          if (s% D_omega_flag) then
     612            0 :             call prune1(s% D_omega, D_omega_old, skip)
     613              :          end if
     614              : 
     615            0 :          if (s% RTI_flag) then
     616            0 :             call prune1(s% dPdr_dRhodr_info, dPdr_dRhodr_info_old, skip)
     617              :          end if
     618              : 
     619              :          contains
     620              : 
     621            0 :          subroutine prune1(p,p_old,skip)
     622              :             real(dp), dimension(:), pointer :: p, p_old
     623              :             integer, intent(in) :: skip
     624              :             integer :: k
     625            0 :             do k=1,nz
     626            0 :                p(k) = p_old(k+skip)
     627              :             end do
     628            0 :          end subroutine prune1
     629              : 
     630            0 :          subroutine prune1_ad(p,p_old,skip)
     631              :             type(auto_diff_real_star_order1), dimension(:), pointer :: p, p_old
     632              :             integer, intent(in) :: skip
     633              :             integer :: k
     634            0 :             do k=1,nz
     635            0 :                p(k) = p_old(k+skip)
     636              :             end do
     637            0 :          end subroutine prune1_ad
     638              : 
     639              :       end subroutine do_prune_mesh_surface
     640              : 
     641              : 
     642              :       subroutine do_xh_pt_var( &
     643              :             s, i_var, nz, nz_old, nzlo, nzhi, comes_from, xh, xh_old, center_val, &
     644              :             xq, xq_old_plus1, xq_new, work, var_old_plus1, var_new, ierr)
     645              :          use interp_1d_def
     646              :          use interp_1d_lib
     647              :          type (star_info), pointer :: s
     648              :          integer, intent(in) :: i_var, nz, nz_old, nzlo, nzhi, comes_from(:)
     649              :          real(dp),intent(in) :: center_val
     650              :          real(dp), dimension(:,:), pointer :: xh, xh_old
     651              :          real(dp), dimension(:), pointer :: work
     652              :          real(dp), dimension(:) :: &
     653              :             xq, xq_old_plus1, var_old_plus1, var_new, xq_new
     654              :          integer, intent(out) :: ierr
     655              : 
     656              :          integer :: n, k
     657              : 
     658              :          include 'formats'
     659              : 
     660              :          ierr = 0
     661              :          n = nzhi - nzlo + 1
     662              : 
     663              :          do k=1,nz_old
     664              :             var_old_plus1(k) = xh_old(i_var,k)
     665              :          end do
     666              :          var_old_plus1(nz_old+1) = center_val
     667              : 
     668              :          call interpolate_vector( &
     669              :             nz_old+1, xq_old_plus1, n, xq_new, &
     670              :             var_old_plus1, var_new, interp_pm, nwork, work, &
     671              :             'mesh_adjust do_xh_pt_var', ierr)
     672              :          if (ierr /= 0) then
     673              :             return
     674              :          end if
     675              : 
     676              :          do k=nzlo,nzhi
     677              :             xh(i_var,k) = max(0d0,var_new(k+1-nzlo))
     678              :          end do
     679              : 
     680              :          n = nzlo - 1
     681              :          if (n > 0) then
     682              :             do k=1,n
     683              :                xh(i_var,k) = xh_old(i_var,k)
     684              :             end do
     685              :          end if
     686              : 
     687              :          if (nzhi < nz) then
     688              :             n = nz - nzhi - 1  ! nz-n = nzhi+1
     689              :             do k=0,n
     690              :                xh(i_var,nz-k) = xh_old(i_var,nz_old-k)
     691              :             end do
     692              :          end if
     693              : 
     694              :       end subroutine do_xh_pt_var
     695              : 
     696              : 
     697           10 :       subroutine do_L( &
     698              :             s, nz, nz_old, nzlo, nzhi, comes_from, xh, xh_old, &
     699           10 :             xq, xq_old_plus1, xq_new, work, L_old_plus1, L_new, ierr)
     700              :          use interp_1d_def
     701              :          use interp_1d_lib
     702              :          type (star_info), pointer :: s
     703              :          integer, intent(in) :: nz, nz_old, nzlo, nzhi, comes_from(:)
     704              :          real(dp), dimension(:,:), pointer :: xh, xh_old
     705              :          real(dp), dimension(:), pointer :: work
     706              :          real(dp), dimension(:) :: &
     707              :             xq, xq_old_plus1, L_old_plus1, L_new, xq_new
     708              :          integer, intent(out) :: ierr
     709              : 
     710              :          integer :: n, i_lum, k
     711              : 
     712              :          include 'formats'
     713              : 
     714           10 :          ierr = 0
     715           10 :          i_lum = s% i_lum
     716           10 :          if (i_lum == 0) return
     717           10 :          n = nzhi - nzlo + 1
     718              : 
     719        12105 :          do k=1,nz_old
     720        12105 :             L_old_plus1(k) = xh_old(i_lum,k)
     721              :          end do
     722           10 :          L_old_plus1(nz_old+1) = s% L_center
     723              : 
     724              :          call interpolate_vector( &
     725              :                nz_old+1, xq_old_plus1, n, xq_new, &
     726              :                L_old_plus1, L_new, interp_pm, nwork, work, &
     727           10 :                'mesh_adjust do_L', ierr)
     728           10 :          if (ierr /= 0) then
     729              :             return
     730              : 
     731              :             write(*,*) 'interpolate_vector failed in do_L for remesh'
     732              :             call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: do_L')
     733              :          end if
     734              : 
     735         1981 :          do k=nzlo,nzhi
     736         1981 :             xh(i_lum,k) = L_new(k+1-nzlo)
     737              :          end do
     738              : 
     739           10 :          n = nzlo - 1
     740           10 :          if (n > 0) then
     741         8430 :             do k=1,n
     742         8430 :                xh(i_lum,k) = xh_old(i_lum,k)
     743              :             end do
     744              :          end if
     745              : 
     746           10 :          if (nzhi < nz) then
     747            4 :             n = nz - nzhi - 1  ! nz-n = nzhi+1
     748          236 :             do k=0,n
     749          236 :                xh(i_lum,nz-k) = xh_old(i_lum,nz_old-k)
     750              :             end do
     751              :          end if
     752              : 
     753           10 :       end subroutine do_L
     754              : 
     755              : 
     756            0 :       subroutine do_alpha_RTI( &
     757              :             s, nz, nz_old, nzlo, nzhi, comes_from, xh, xh_old, &
     758            0 :             xq, xq_old_plus1, xq_new, work, alpha_RTI_old_plus1, alpha_RTI_new, ierr)
     759           10 :          use interp_1d_def
     760              :          use interp_1d_lib
     761              :          type (star_info), pointer :: s
     762              :          integer, intent(in) :: nz, nz_old, nzlo, nzhi, comes_from(:)
     763              :          real(dp), dimension(:,:), pointer :: xh, xh_old
     764              :          real(dp), dimension(:), pointer :: work
     765              :          real(dp), dimension(:) :: &
     766              :             xq, xq_old_plus1, alpha_RTI_old_plus1, alpha_RTI_new, xq_new
     767              :          integer, intent(out) :: ierr
     768              : 
     769              :          integer :: n, i_alpha_RTI, k
     770              : 
     771              :          include 'formats'
     772              : 
     773              :          ierr = 0
     774            0 :          i_alpha_RTI = s% i_alpha_RTI
     775            0 :          n = nzhi - nzlo + 1
     776              : 
     777            0 :          do k=1,nz_old
     778            0 :             alpha_RTI_old_plus1(k) = xh_old(i_alpha_RTI,k)
     779              :          end do
     780            0 :          alpha_RTI_old_plus1(nz_old+1) = 0
     781              : 
     782              :          call interpolate_vector( &
     783              :                nz_old+1, xq_old_plus1, n, xq_new, &
     784              :                alpha_RTI_old_plus1, alpha_RTI_new, interp_pm, nwork, work, &
     785            0 :                'mesh_adjust do_alpha_RTI', ierr)
     786            0 :          if (ierr /= 0) then
     787              :             return
     788              :          end if
     789              : 
     790            0 :          do k=nzlo,nzhi
     791            0 :             xh(i_alpha_RTI,k) = max(0d0,alpha_RTI_new(k+1-nzlo))
     792              :          end do
     793              : 
     794            0 :          n = nzlo - 1
     795            0 :          if (n > 0) then
     796            0 :             do k=1,n
     797            0 :                xh(i_alpha_RTI,k) = xh_old(i_alpha_RTI,k)
     798              :             end do
     799              :          end if
     800              : 
     801            0 :          if (nzhi < nz) then
     802            0 :             n = nz - nzhi - 1  ! nz-n = nzhi+1
     803            0 :             do k=0,n
     804            0 :                xh(i_alpha_RTI,nz-k) = xh_old(i_alpha_RTI,nz_old-k)
     805              :             end do
     806              :          end if
     807              : 
     808            0 :       end subroutine do_alpha_RTI
     809              : 
     810              : 
     811           20 :       subroutine do_interp_pt_val( &
     812              :             s, nz, nz_old, nzlo, nzhi, val, val_old, center_val, &
     813           20 :             xq, xq_old_plus1, xq_new, force_non_negative, &
     814           40 :             work, val_old_plus1, val_new, ierr)
     815            0 :          use interp_1d_def
     816              :          use interp_1d_lib
     817              :          type (star_info), pointer :: s
     818              :          integer, intent(in) :: nz, nz_old, nzlo, nzhi
     819              :          real(dp), dimension(:), pointer :: val, val_old
     820              :          real(dp), intent(in) :: center_val
     821              :          real(dp), dimension(:), pointer :: work
     822              :          real(dp), dimension(:) :: &
     823              :             xq, xq_old_plus1, xq_new, val_old_plus1, val_new
     824              :          logical, intent(in) :: force_non_negative
     825              :          integer, intent(out) :: ierr
     826              :          integer :: n, k
     827              : 
     828              :          include 'formats'
     829              : 
     830              :          ierr = 0
     831           20 :          n = nzhi - nzlo + 1
     832              : 
     833        24210 :          do k=1,nz_old
     834        24210 :             val_old_plus1(k) = val_old(k)
     835              :          end do
     836           20 :          val_old_plus1(nz_old+1) = center_val
     837              : 
     838              :          call interpolate_vector( &
     839              :                nz_old+1, xq_old_plus1, n, xq_new, &
     840              :                val_old_plus1, val_new, interp_pm, nwork, work, &
     841           20 :                'mesh_adjust do_interp_pt_val', ierr)
     842           20 :          if (ierr /= 0) then
     843              :             return
     844              :          end if
     845              : 
     846         3962 :          do k=nzlo,nzhi
     847         3962 :             val(k) = val_new(k+1-nzlo)
     848              :          end do
     849              : 
     850           20 :          n = nzlo - 1
     851           20 :          if (n > 0) then
     852        16860 :             do k=1,n
     853        16860 :                val(k) = val_old(k)
     854              :             end do
     855              :          end if
     856              : 
     857           20 :          if (nzhi < nz) then
     858            8 :             n = nz - nzhi - 1  ! nz-n = nzhi+1
     859          472 :             do k=0,n
     860          472 :                val(nz-k) = val_old(nz_old-k)
     861              :             end do
     862              :          end if
     863              : 
     864           20 :          if (force_non_negative) then
     865         3962 :             do k=nzlo,nzhi
     866         3962 :                if (val(k) < 0) val(k) = 0
     867              :             end do
     868              :          end if
     869              : 
     870           20 :       end subroutine do_interp_pt_val
     871              : 
     872              : 
     873              :       subroutine do_interp_cell_val( &
     874              :             s, nz, nz_old, nzlo, nzhi, val_new_out, val_old, &
     875              :             xq, xq_old_plus1, dq, dq_old, work, val_old_plus1, val_new, ierr)
     876           20 :          use interp_1d_def
     877              :          use interp_1d_lib
     878              :          type (star_info), pointer :: s
     879              :          integer, intent(in) :: nz, nz_old, nzlo, nzhi
     880              :          real(dp), dimension(:), pointer :: val_new_out, val_old
     881              :          real(dp), dimension(:), pointer :: work
     882              :          real(dp), dimension(:) :: &
     883              :             xq, xq_old_plus1, dq, dq_old, val_old_plus1, val_new
     884              :          integer, intent(out) :: ierr
     885              : 
     886              :          real(dp), pointer, dimension(:) :: &
     887              :             mid_xq_new, mid_xq_old_plus1
     888              :          integer :: n, i, k
     889              : 
     890              :          ierr = 0
     891              :          n = nzhi - nzlo + 1
     892              :          call do_alloc(ierr)
     893              :          if (ierr /= 0) return
     894              : 
     895              :          do k=1,nz_old
     896              :             val_old_plus1(k) = val_old(k)
     897              :             mid_xq_old_plus1(k) = xq_old_plus1(k) + 0.5d0*dq_old(k)
     898              :          end do
     899              :          val_old_plus1(nz_old+1) = val_old_plus1(nz_old)
     900              :          mid_xq_old_plus1(nz_old+1) = 1
     901              :          do i=1,n
     902              :             mid_xq_new(i) = xq(nzlo+i-1) + 0.5d0*dq(nzlo+i-1)
     903              :          end do
     904              : 
     905              :          call interpolate_vector( &
     906              :                nz_old+1, mid_xq_old_plus1, n, mid_xq_new, &
     907              :                val_old_plus1, val_new, interp_pm, nwork, work, &
     908              :                'mesh_adjust do_interp_cell_val', ierr)
     909              :          if (ierr /= 0) then
     910              :             call dealloc
     911              :             return
     912              :          end if
     913              : 
     914              :          do i=1,n
     915              :             val_new_out(nzlo+i-1) = val_new(i)
     916              :          end do
     917              : 
     918              :          n = nzlo - 1
     919              :          if (n > 0) then
     920              :             do i=1,n
     921              :                val_new_out(i) = val_old(i)
     922              :             end do
     923              :          end if
     924              : 
     925              :          if (nzhi < nz) then
     926              :             n = nz - nzhi - 1  ! nz-n = nzhi+1
     927              :             do i=0,n
     928              :                val_new_out(nz-i) = val_old(nz_old-i)
     929              :             end do
     930              :          end if
     931              : 
     932              :          call dealloc
     933              : 
     934              :          contains
     935              : 
     936              :          subroutine do_alloc(ierr)
     937              :             integer, intent(out) :: ierr
     938              :             call do_work_arrays(.true.,ierr)
     939              :          end subroutine do_alloc
     940              : 
     941              :          subroutine dealloc
     942              :             integer :: ierr
     943              :             call do_work_arrays(.false.,ierr)
     944              :          end subroutine dealloc
     945              : 
     946              :          subroutine do_work_arrays(alloc_flag, ierr)
     947              :             use alloc, only: work_array
     948              :             logical, intent(in) :: alloc_flag
     949              :             integer, intent(out) :: ierr
     950              :             logical, parameter :: crit = .false.
     951              :             ierr = 0
     952              :             call work_array(s, alloc_flag, crit, &
     953              :                 mid_xq_old_plus1, nz_old+1, nz_alloc_extra, 'mesh_adjust', ierr)
     954              :             if (ierr /= 0) return
     955              :             call work_array(s, alloc_flag, crit, &
     956              :                 mid_xq_new, n, nz_alloc_extra, 'mesh_adjust', ierr)
     957              :             if (ierr /= 0) return
     958              :          end subroutine do_work_arrays
     959              : 
     960              :       end subroutine do_interp_cell_val
     961              : 
     962              : 
     963           10 :       subroutine do_lnR_and_lnd( &
     964           40 :             s, nz, nz_old, nzlo, nzhi, cell_type, comes_from, &
     965           10 :             xh, xh_old, xmstar, lnd_old, lnPgas_old, &
     966           40 :             dqbar, dqbar_old, old_r, old_m, old_rho, &
     967           20 :             dq, dq_old, xq, xq_old_plus1, density_new, work, &
     968           30 :             Vol_old_plus1, Vol_new, new_r, Vol_init, &
     969           20 :             interp_Vol_new, interp_xq, density_init, ierr)
     970              :          use interp_1d_def
     971              :          use interp_1d_lib
     972              :          use num_lib
     973              :          type (star_info), pointer :: s
     974              :          integer, intent(in) :: nz, nz_old, nzlo, nzhi, comes_from(:)
     975              :          integer :: cell_type(:)
     976              :          real(dp), dimension(:,:), pointer :: xh, xh_old
     977              :          real(dp), intent(in) :: xmstar
     978              :          real(dp), dimension(:), pointer :: work
     979              :          real(dp), dimension(:) :: &
     980              :             lnd_old, lnPgas_old, dqbar, dqbar_old, old_r, old_m, old_rho, &
     981              :             xq, dq, dq_old, xq_old_plus1, density_new, &
     982              :             Vol_old_plus1, Vol_new, new_r, Vol_init, &
     983              :             interp_Vol_new, interp_xq, density_init
     984              :          integer, intent(out) :: ierr
     985              : 
     986              :          integer :: k, from_k, n, interp_lo, interp_hi, interp_n
     987           10 :          real(dp) :: Vol_min, Vol_max, cell_Vol, Vol_center, Vm1, V00, Vp1
     988              : 
     989              :          logical, parameter :: dbg = .false., trace_PE_residual = .false.
     990              : 
     991              :          include 'formats'
     992              : 
     993              :          ! NOTE: for interpolating volume, need to add point at center
     994              : 
     995           10 :          ierr = 0
     996              : 
     997           10 :          interp_lo = max(1, nzlo-1)
     998           10 :          interp_hi = min(nz, nzhi+1)
     999           10 :          interp_n = interp_hi - interp_lo + 1
    1000              : 
    1001        12105 :          do k=1,nz_old
    1002        12105 :             Vol_old_plus1(k) = four_thirds_pi*old_r(k)*old_r(k)*old_r(k)
    1003              :          end do
    1004           10 :          Vol_center = four_thirds_pi*s% R_center*s% R_center*s% R_center
    1005           10 :          Vol_old_plus1(nz_old+1) = Vol_center
    1006              : 
    1007              :          ! testing -- check for Vol_old_plus1 strictly decreasing
    1008        12105 :          do k = 2, nz_old+1
    1009        12105 :             if (Vol_old_plus1(k) >= Vol_old_plus1(k-1)) then
    1010            0 :                ierr = -1
    1011            0 :                if (.not. dbg) return
    1012              :                write(*,3) 'bad old vol', k, nz_old
    1013              :                write(*,1) 'Vol_old_plus1(k)', Vol_old_plus1(k)
    1014              :                write(*,1) 'Vol_old_plus1(k-1)', Vol_old_plus1(k-1)
    1015              :                write(*,'(A)')
    1016              :                call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: do_lnR_and_lnd')
    1017              :             end if
    1018              :          end do
    1019              : 
    1020              :          ! testing -- check for q strictly decreasing
    1021        10623 :          do k = 2, nz
    1022        10623 :             if (xq(k) <= xq(k-1)) then
    1023            0 :                ierr = -1
    1024            0 :                if (.not. dbg) return
    1025              : 
    1026              :                write(*,3) 'bad xq', k, nz, xq(k), xq(k-1)
    1027              :                call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: do_lnR_and_lnd')
    1028              :             end if
    1029              :          end do
    1030              : 
    1031         1995 :          do k=1,interp_n
    1032         1995 :             interp_xq(k) = xq(interp_lo+k-1)
    1033              :          end do
    1034              : 
    1035              :          call interpolate_vector( &
    1036              :                nz_old+1, xq_old_plus1, interp_n, interp_xq, Vol_old_plus1, &
    1037           10 :                interp_Vol_new, interp_pm, nwork, work, 'mesh_adjust do_lnR_and_lnd', ierr)
    1038           10 :          if (ierr /= 0) then
    1039              :             if (.not. dbg) return
    1040              :             write(*,*) 'failed in interpolate_vector'
    1041              :             call mesa_error(__FILE__,__LINE__,'debug: mesh_adjust')
    1042              :          end if
    1043              : 
    1044         1995 :          do k=1,interp_n
    1045         1995 :             Vol_new(interp_lo+k-1) = interp_Vol_new(k)
    1046              :          end do
    1047              : 
    1048           10 :          if (Vol_new(interp_lo+1) >= Vol_new(interp_lo)) then
    1049            0 :             Vol_new(interp_lo+1) = (Vol_new(interp_lo) + Vol_new(interp_lo+2))/2
    1050              :             if (dbg) write(*,2) 'fix Vol_new at lo+1', interp_lo+1, Vol_new(interp_lo+1)
    1051            0 :             if (Vol_new(interp_lo+1) >= Vol_new(interp_lo)) then
    1052            0 :                ierr = -1
    1053            0 :                if (.not. dbg) return
    1054              :                write(*,*) '(Vol_new(interp_lo+1) >= Vol_new(interp_lo))'
    1055              :                call mesa_error(__FILE__,__LINE__,'debug: mesh_adjust')
    1056              :             end if
    1057              :          end if
    1058              : 
    1059         1975 :          do k = interp_lo+1, interp_hi-1
    1060         1975 :             if (Vol_new(k+1) >= Vol_new(k) .or. Vol_new(k) >= Vol_new(k-1)) then
    1061              :                if (dbg) write(*,2) 'fix interpolated Vol_new', &
    1062              :                   k, Vol_new(k+1), Vol_new(k), Vol_new(k-1)
    1063            0 :                Vol_min = minval(Vol_new(k-1:k+1))
    1064            0 :                Vol_max = maxval(Vol_new(k-1:k+1))
    1065            0 :                if (Vol_min == Vol_max .or. is_bad(Vol_min) .or. is_bad(Vol_max)) then
    1066            0 :                   ierr = -1
    1067            0 :                   if (s% stop_for_bad_nums) then
    1068            0 :                      write(*,2) 'Vol_min', k, Vol_min
    1069            0 :                      write(*,2) 'Vol_max', k, Vol_max
    1070            0 :                      call mesa_error(__FILE__,__LINE__,'mesh_adjust')
    1071              :                   end if
    1072            0 :                   if (.not. dbg) return
    1073              :                   write(*,1) 'Vol_min', Vol_min
    1074              :                   write(*,1) 'Vol_max', Vol_max
    1075              :                   call mesa_error(__FILE__,__LINE__,'debug: mesh_adjust')
    1076              :                end if
    1077            0 :                Vm1 = Vol_new(k-1)
    1078            0 :                V00 = Vol_new(k)
    1079            0 :                Vp1 = Vol_new(k+1)
    1080            0 :                Vol_new(k-1) = Vol_max
    1081            0 :                Vol_new(k) = (Vol_max + Vol_min)/2
    1082            0 :                Vol_new(k+1) = Vol_min
    1083              :                if (dbg) write(*,2) 'new Vol_new',  &
    1084              :                   k, Vol_new(k+1), Vol_new(k), Vol_new(k-1)
    1085            0 :                if (Vol_new(k+1) >= Vol_new(k) .or. Vol_new(k) >= Vol_new(k-1)) then
    1086            0 :                   ierr = -1
    1087            0 :                   if (.not. dbg) return
    1088              :                   write(*,1) 'Vol_new(k-1)', Vol_new(k-1)
    1089              :                   write(*,1) 'Vol_new(k)', Vol_new(k)
    1090              :                   write(*,1) 'Vol_new(k+1)', Vol_new(k+1)
    1091              :                   call mesa_error(__FILE__,__LINE__,'debug: do_lnR_and_lnd in mesh adjust: interpolation gave non-pos volume')
    1092              :                end if
    1093              :             end if
    1094              :          end do
    1095              : 
    1096           10 :          call set1_new_r(nzlo)
    1097         1975 :          do k = nzlo, min(nzhi,nz-1)
    1098         1965 :             if (ierr /= 0) cycle
    1099              : 
    1100         1965 :             call set1_new_r(k+1)
    1101              : 
    1102         1965 :             if (cell_type(k) == unchanged_type) then
    1103          493 :                call store_lnd_in_xh(s, k, lnd_old(comes_from(k)), xh)
    1104          493 :                density_new(k) = old_rho(comes_from(k))
    1105          493 :                cycle
    1106              :             end if
    1107              : 
    1108         1472 :             if (new_r(k) <= new_r(k+1)) then
    1109              :                if (dbg) then
    1110              :                   write(*,*) 'do_lnR_and_lnd: (new_r(k) <= new_r(k+1))'
    1111              :                   stop
    1112              :                end if
    1113            0 :                ierr = -1; cycle
    1114              :             end if
    1115              : 
    1116         1472 :             cell_Vol = Vol_new(k)-Vol_new(k+1)
    1117         1472 :             if (cell_Vol <= 0) then
    1118              :                if (dbg) then
    1119              :                   write(*,2) 'do_lnR_and_lnd: cell_Vol <= 0', k
    1120              :                end if
    1121            0 :                ierr = -1; cycle
    1122              :             end if
    1123         1472 :             if (dq(k) <= 0) then
    1124              :                if (dbg) then
    1125              :                   write(*,2) 'do_lnR_and_lnd: dq(k) <= 0', k
    1126              :                end if
    1127            0 :                ierr = -1; cycle
    1128              :             end if
    1129         1472 :             density_new(k) = xmstar*dq(k)/cell_Vol
    1130         1482 :             call store_rho_in_xh(s, k, density_new(k), xh)
    1131              : 
    1132              :          end do
    1133              : 
    1134           10 :          if (ierr /= 0) then
    1135              :             if (.not. dbg) return
    1136              :             call mesa_error(__FILE__,__LINE__,'debug: failed in mesh adjust do_lnR_and_lnd')
    1137              :          end if
    1138              : 
    1139           10 :          n = nzlo - 1
    1140           10 :          if (n > 0) then
    1141         8430 :             do k=1,n
    1142         8420 :                new_r(k) = old_r(k)
    1143         8420 :                density_new(k) = old_rho(k)
    1144         8430 :                Vol_new(k) = four_thirds_pi*new_r(k)*new_r(k)*new_r(k)
    1145              :             end do
    1146              :          end if
    1147              : 
    1148           10 :          if (nzhi < nz) then
    1149            4 :             n = nz - nzhi - 1  ! nz-n = nzhi+1
    1150          236 :             do k=0,n
    1151          232 :                new_r(nz-k) = old_r(nz_old-k)
    1152          232 :                density_new(nz-k) = old_rho(nz_old-k)
    1153          236 :                Vol_new(nz-k) = four_thirds_pi*new_r(nz-k)*new_r(nz-k)*new_r(nz-k)
    1154              :             end do
    1155              :          else  ! nzhi == nz
    1156            6 :             density_new(nz) = xmstar*dq(nz)/(Vol_new(nz) - Vol_center)
    1157            6 :             new_r(nz) = pow(Vol_new(nz)/four_thirds_pi, one_third)
    1158              : 
    1159              :             if (dbg) then
    1160              :                write(*,2) 'old_rho(nz_old)', nz_old, old_rho(nz_old)
    1161              :                write(*,2) 'density_new(nz)', nz, density_new(nz)
    1162              :             end if
    1163              : 
    1164              :          end if
    1165              : 
    1166        10633 :          do k=1,nz
    1167        10623 :             Vol_init(k) = Vol_new(k)
    1168        10633 :             density_init(k) = density_new(k)
    1169              :          end do
    1170              : 
    1171        10643 :          do k=1,nz
    1172        10623 :             from_k = comes_from(k)
    1173        10623 :             if (new_r(k) == old_r(from_k)) then
    1174         9187 :                xh(s%i_lnR,k) = xh_old(s%i_lnR,from_k)
    1175              :             else
    1176         1436 :                call store_r_in_xh(s,k,new_r(k),xh)
    1177              :             end if
    1178        10633 :             if (density_new(k) == old_rho(from_k)) then
    1179         9147 :                xh(s%i_lnd,k) = xh_old(s%i_lnd,from_k)
    1180              :             else
    1181         1476 :                call store_rho_in_xh(s,k,density_new(k),xh)
    1182              :             end if
    1183              :          end do
    1184              : 
    1185              : 
    1186              :          contains
    1187              : 
    1188         1975 :          subroutine set1_new_r(k)
    1189              :             integer, intent(in) :: k
    1190              :             include 'formats'
    1191         1975 :             if (cell_type(k) == unchanged_type) then
    1192          503 :                new_r(k) = old_r(comes_from(k))
    1193              :             else
    1194         1472 :                new_r(k) = pow(Vol_new(k)/four_thirds_pi, one_third)
    1195              :             end if
    1196           10 :          end subroutine set1_new_r
    1197              : 
    1198              : 
    1199              :       end subroutine do_lnR_and_lnd
    1200              : 
    1201              : 
    1202        10623 :       subroutine do_xa( &
    1203        10623 :             s, nz, nz_old, k, species, cell_type, comes_from, &
    1204        10623 :             xa, xa_old, xa_c0, xa_c1, xa_c2, &
    1205              :             xq, dq, xq_old,  dq_old, mesh_adjust_use_quadratic, ierr)
    1206              :          use chem_def, only: chem_isos
    1207              :          type (star_info), pointer :: s
    1208              :          integer, intent(in) :: nz, nz_old, species, k, cell_type(:), comes_from(:)
    1209              :          real(dp), dimension(:,:), pointer :: xa, xa_old
    1210              :          real(dp), dimension(:,:) :: xa_c0, xa_c1, xa_c2
    1211              :          real(dp), dimension(:), pointer :: xq, dq, xq_old, dq_old
    1212              :          logical, intent(in) :: mesh_adjust_use_quadratic
    1213              :          integer, intent(out) :: ierr
    1214              : 
    1215              :          integer :: j, jj, k_old, k_old_last, kdbg, order
    1216        95607 :          real(dp) :: xq_outer, cell_dq, xa_sum, total(species)
    1217              :          logical :: dbg_get_integral
    1218              : 
    1219              :          include 'formats'
    1220              : 
    1221        10623 :          ierr = 0
    1222              : 
    1223        10623 :          kdbg = -1074
    1224              : 
    1225        10623 :          if (mesh_adjust_use_quadratic) then
    1226        10623 :             order = 2
    1227              :          else
    1228            0 :             order = 1
    1229              :          end if
    1230              : 
    1231        10623 :          if (cell_type(k) == unchanged_type .or. &
    1232              :                cell_type(k) == revised_type) then
    1233        82359 :             do j=1,species
    1234        82359 :                xa(j,k) = xa_old(j,comes_from(k))
    1235              :             end do
    1236              :             return
    1237              :          end if
    1238              : 
    1239         1472 :          xq_outer = xq(k)
    1240         1472 :          if (k == nz) then
    1241            0 :             cell_dq = 1 - xq_outer
    1242              :          else
    1243         1472 :             cell_dq = dq(k)
    1244              :          end if
    1245              : 
    1246         1472 :          k_old = max(comes_from(k)-1,1)
    1247              : 
    1248              :          ! sum the old abundances between xq_outer and xq_inner
    1249         1472 :          dbg_get_integral = .false.
    1250        13248 :          total(:) = 0
    1251        13248 :          do j=1,species
    1252        11776 :             dbg_get_integral = (k == kdbg) .and. (j == 1)  ! h1
    1253        11776 :             if (dbg_get_integral) write(*,2) trim(chem_isos% name(s% chem_id(j)))
    1254              :             call get_xq_integral( &
    1255              :                k_old, nz_old, xq_old, xq_outer, cell_dq, &
    1256              :                order, xa_c0(:,j), xa_c1(:,j), xa_c2(:,j), &
    1257        13248 :                total(j), dbg_get_integral, k_old_last, ierr)
    1258              :          end do
    1259              : 
    1260        13248 :          xa(:,k) = total(:)/cell_dq
    1261              : 
    1262         1472 :          if (k == kdbg) then
    1263            0 :             do j=1,species
    1264            0 :                write(*,2) 'new ' // trim(chem_isos% name(s% chem_id(j))), k, xa(j,k)
    1265              :             end do
    1266              :          end if
    1267              : 
    1268        13248 :          do j=1,species
    1269        13248 :             if (xa(j,k) > 1 + 1d-8 .or. xa(j,k) < -1d-8) then
    1270            0 :                ierr = -1
    1271            0 :                return
    1272              : 
    1273              :                do jj=1,species
    1274              :                   write(*,1) 'xa ' // trim(chem_isos% name(s% chem_id(jj))), xa(jj,k)
    1275              :                end do
    1276              :                write(*,'(A)')
    1277              :                write(*,2) 'sum xa', k, sum(xa(:,k))
    1278              :                write(*,'(A)')
    1279              :                write(*,2) 'xa ' // trim(chem_isos% name(s% chem_id(j))), k, xa(j,k)
    1280              :                write(*,'(A)')
    1281              :                write(*,2) 'xq_outer', k, xq_outer
    1282              :                write(*,2) 'xq_inner', k, xq_outer + cell_dq
    1283              :                write(*,2) 'cell_dq', k, cell_dq
    1284              :                write(*,'(A)')
    1285              :                write(*,2) 'xq_old(k_old)', k_old, xq_old(k_old)
    1286              :                write(*,2) 'xq_inner(k_old)', k_old, xq_old(k_old)+dq_old(k_old)
    1287              :                write(*,2) 'dq_old(k_old)', k_old, dq_old(k_old)
    1288              :                write(*,'(A)')
    1289              :                write(*,2) 'xa_c0(k_old,j)', k_old, xa_c0(k_old,j)
    1290              :                write(*,2) 'xa_c1(k_old,j)', k_old, xa_c1(k_old,j)
    1291              :                write(*,2) 'xa_c2(k_old,j)', k_old, xa_c2(k_old,j)
    1292              :                write(*,'(A)')
    1293              :                write(*,2) 'old outer', k_old, xa_c0(k_old,j) + xa_c1(k_old,j)*dq_old(k_old)/2
    1294              :                write(*,2) 'old inner', k_old, xa_c0(k_old,j) - xa_c1(k_old,j)*dq_old(k_old)/2
    1295              :                write(*,'(A)')
    1296              :                call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: do_xa')
    1297              :             end if
    1298              :          end do
    1299              : 
    1300        13248 :          xa_sum = sum(xa(:,k))
    1301              :          !write(*,1) 'xa_sum', xa_sum
    1302              : 
    1303         1472 :          if (is_bad(xa_sum)) then
    1304            0 :             ierr = -1
    1305            0 :             if (s% stop_for_bad_nums) then
    1306            0 :                write(*,2) 'xa_sum', k, xa_sum
    1307            0 :                call mesa_error(__FILE__,__LINE__,'mesh adjust: do_xa')
    1308              :             end if
    1309            0 :             return
    1310              : 
    1311              :             write(*,*) 'xa_sum', xa_sum
    1312              :             write(*,*) 'bug in revise mesh, do_xa bad num: k', k
    1313              :             call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: do_xa')
    1314              :          end if
    1315              : 
    1316         1472 :          if (abs(1-xa_sum) > 1d-3) then
    1317            0 :             ierr = -1
    1318            0 :             return
    1319              :          end if
    1320              : 
    1321        13248 :          xa(:,k) = xa(:,k) / xa_sum
    1322              : 
    1323        10623 :       end subroutine do_xa
    1324              : 
    1325              : 
    1326        10623 :       subroutine do1_lnT( &
    1327              :             s, nz_old, k, &
    1328        10623 :             species, cell_type, comes_from, &
    1329              :             xa, xh, xh_old, &
    1330        10623 :             xq, dq, xq_old, dq_old, eta_old, energy_old, lnT_old, &
    1331        10623 :             specific_PE_old, specific_KE_old, w_old, &
    1332        21246 :             density_new, energy_new, ierr)
    1333        10623 :          use eos_def
    1334              :          use star_utils, only: set_rmid, cell_specific_PE, cell_specific_KE
    1335              :          type (star_info), pointer :: s
    1336              :          integer, intent(in) :: nz_old, k, species, cell_type(:), comes_from(:)
    1337              :          real(dp), dimension(:,:), pointer :: xa, xh, xh_old
    1338              :          real(dp), dimension(:) :: &
    1339              :             xq, dq, xq_old, dq_old, eta_old, energy_old, lnT_old, &
    1340              :             specific_PE_old, specific_KE_old, w_old, density_new, energy_new
    1341              :          integer, intent(out) :: ierr
    1342              : 
    1343              :          integer :: k_old
    1344              :          real(dp) :: &
    1345        21246 :             Rho, logRho, xq_outer, cell_dq, avg_energy, avg_PE, avg_KE, &
    1346        21246 :             new_PE, new_KE, max_delta_energy, delta_energy, revised_energy, &
    1347        95607 :             sum_lnT, avg_lnT, new_lnT, sum_energy, new_xa(species), &
    1348        10623 :             d_dlnR00, d_dlnRp1, d_dv00, d_dvp1
    1349              : 
    1350              :          include 'formats'
    1351              : 
    1352        10623 :          ierr = 0
    1353        95607 :          new_xa(:) = xa(:,k)
    1354        10623 :          k_old = comes_from(k)
    1355              : 
    1356        10623 :          if (cell_type(k) == unchanged_type) then
    1357         9151 :             xh(s%i_lnT, k) = xh_old(s%i_lnT, k_old)
    1358         9151 :             energy_new(k) = energy_old(k_old)
    1359         9151 :             if (is_bad(energy_old(k_old))) then
    1360            0 :                write(*,2) 'energy_old(k_old)', k_old, energy_old(k_old)
    1361            0 :                call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: do1_lnT')
    1362              :             end if
    1363         9151 :             return
    1364              :          end if
    1365              : 
    1366         1472 :          xq_outer = xq(k)
    1367         1472 :          cell_dq = dq(k)
    1368              : 
    1369         1472 :          if (cell_type(k) == revised_type) then
    1370            0 :             avg_lnT = get_lnT_from_xh(s, k, xh_old)
    1371              :          else  ! find average lnT between xq_outer and xq_inner
    1372              :             call get_old_value_integral( &
    1373              :                k, k_old, nz_old, xq_old, dq_old, xq_outer, cell_dq, &
    1374         1472 :                lnT_old, sum_lnT, dbg, ierr)
    1375         1472 :             if (ierr /= 0) then
    1376              :                if (dbg) write(*,*) 'get_old_value_integral lnT failed for do1_lnT'
    1377              :                if (.not. dbg) return
    1378              :                call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: do1_lnT')
    1379              :             end if
    1380         1472 :             avg_lnT = sum_lnT/cell_dq
    1381              :          end if
    1382              : 
    1383         1472 :          if (is_bad(avg_lnT) .or. avg_lnT < 0 .or. avg_lnT > 100) then
    1384            0 :             ierr = -1
    1385            0 :             if (s% stop_for_bad_nums) then
    1386            0 :                write(*,2) 'avg_lnT', k, avg_lnT
    1387            0 :                call mesa_error(__FILE__,__LINE__,'mesh adjust: do1_lnT')
    1388              :             end if
    1389            0 :             return
    1390              :          end if
    1391              : 
    1392         1472 :          if (.not. s% mesh_adjust_get_T_from_E) then
    1393            0 :             call store_lnT_in_xh(s, k, avg_lnT, xh)
    1394            0 :             energy_new(k) = energy_old(k_old)
    1395            0 :             if (is_bad(energy_old(k_old))) then
    1396            0 :                write(*,2) 'energy_old(k_old)', k_old, energy_old(k_old)
    1397            0 :                call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: do1_lnT')
    1398              :             end if
    1399            0 :             return
    1400              :          end if
    1401              : 
    1402         1472 :          if (eta_old(k_old) >= eta_limit) then
    1403            0 :             call store_lnT_in_xh(s, k, avg_lnT, xh)
    1404            0 :             energy_new(k) = energy_old(k_old)
    1405            0 :             if (is_bad(energy_old(k_old))) then
    1406            0 :                write(*,2) 'eta_old(k_old)', k_old, eta_old(k_old)
    1407            0 :                write(*,2) 'energy_old(k_old)', k_old, energy_old(k_old)
    1408            0 :                call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: do1_lnT')
    1409              :             end if
    1410            0 :             return
    1411              :          end if
    1412              : 
    1413              :          if (dbg) write(*,2) 'eta_old(k_old)', k_old, eta_old(k_old)
    1414              : 
    1415         1472 :          if (cell_type(k) == revised_type) then
    1416            0 :             avg_energy = energy_old(k_old)
    1417              :          else  ! find average internal energy between q_outer and q_inner
    1418              :             call get_old_value_integral( &
    1419              :                k, k_old, nz_old, xq_old, dq_old, xq_outer, cell_dq, &
    1420         1472 :                energy_old, sum_energy, dbg, ierr)
    1421         1472 :             if (ierr /= 0) then
    1422              :                if (dbg) write(*,*) 'get_old_value_integral failed for do1_lnT'
    1423              :                if (.not. dbg) return
    1424              :                call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: energy_old do1_lnT')
    1425              :             end if
    1426         1472 :             avg_energy = sum_energy/cell_dq
    1427              :          end if
    1428              : 
    1429         1472 :          if (s% max_rel_delta_IE_for_mesh_total_energy_balance == 0d0) then
    1430              : 
    1431            0 :             energy_new(k) = avg_energy
    1432              : 
    1433              :          else
    1434              : 
    1435         1472 :             if (cell_type(k) == revised_type) then
    1436            0 :                avg_PE = specific_PE_old(k_old)
    1437              :             else  ! find average potential energy between q_outer and q_inner
    1438              :                call get_old_value_integral( &
    1439              :                   k, k_old, nz_old, xq_old, dq_old, xq_outer, cell_dq, &
    1440         1472 :                   specific_PE_old, sum_energy, dbg, ierr)
    1441         1472 :                if (ierr /= 0) then
    1442              :                   if (dbg) write(*,*) 'get_old_value_integral failed for do1_lnT'
    1443              :                   if (.not. dbg) return
    1444              :                   call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: specific_PE_old do1_lnT')
    1445              :                end if
    1446         1472 :                avg_PE = sum_energy/cell_dq
    1447              :             end if
    1448              : 
    1449         1472 :             if (cell_type(k) == revised_type) then
    1450            0 :                avg_KE = specific_KE_old(k_old)
    1451              :             else  ! find average kinetic energy between q_outer and q_inner
    1452              :                call get_old_value_integral( &
    1453              :                   k, k_old, nz_old, xq_old, dq_old, xq_outer, cell_dq, &
    1454         1472 :                   specific_KE_old, sum_energy, dbg, ierr)
    1455         1472 :                if (ierr /= 0) then
    1456              :                   if (dbg) write(*,*) 'get_old_value_integral failed for do1_lnT'
    1457              :                   if (.not. dbg) return
    1458              :                   call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: specific_KE_old do1_lnT')
    1459              :                end if
    1460         1472 :                avg_KE = sum_energy/cell_dq
    1461              :             end if
    1462              : 
    1463         1472 :             if (ierr /= 0) return
    1464         1472 :             new_PE = cell_specific_PE(s,k,d_dlnR00,d_dlnRp1)
    1465         1472 :             if (s% u_flag) then
    1466            0 :                s% u(k) = s% xh(s% i_u,k)
    1467         1472 :             else if (s% v_flag) then
    1468            0 :                s% v(k) = s% xh(s% i_v,k)
    1469            0 :                if (k < s% nz) s% v(k+1) = s% xh(s% i_v,k+1)
    1470              :             end if
    1471         1472 :             new_KE = cell_specific_KE(s,k,d_dv00,d_dvp1)
    1472              : 
    1473         1472 :             max_delta_energy = avg_energy*s% max_rel_delta_IE_for_mesh_total_energy_balance
    1474         1472 :             delta_energy = avg_PE + avg_KE - (new_PE + new_KE)
    1475         1472 :             if (abs(delta_energy) > max_delta_energy) then
    1476            0 :                delta_energy = sign(max_delta_energy,delta_energy)
    1477              :             end if
    1478         1472 :             energy_new(k) = avg_energy + delta_energy
    1479              : 
    1480         1472 :             if (energy_new(k) <= 0d0) then
    1481            0 :                write(*,2) 'energy_new(k) <= 0d0', k, energy_new(k), avg_energy
    1482            0 :                energy_new(k) = avg_energy
    1483              :             end if
    1484              : 
    1485              :          end if
    1486              : 
    1487              :          ! call eos to calculate lnT from new internal energy
    1488              : 
    1489         1472 :          Rho = density_new(k)
    1490         1472 :          logRho = log10(Rho)
    1491              :          call set_lnT_for_energy( &
    1492              :             s, k, &
    1493              :             s% net_iso(ih1), s% net_iso(ihe3), s% net_iso(ihe4), species, new_xa, &
    1494         1472 :             Rho, logRho, energy_new(k), avg_lnT, new_lnT, revised_energy, ierr)
    1495         1472 :          if (ierr /= 0) then
    1496              :             if (dbg) write(*,*) 'set_lnT_for_energy failed', k
    1497            0 :             new_lnT = avg_lnT
    1498            0 :             energy_new(k) = energy_old(k_old)
    1499            0 :             ierr = 0
    1500              :          end if
    1501              : 
    1502         1472 :          call store_lnT_in_xh(s, k, new_lnT, xh)
    1503              : 
    1504         1472 :          if (ierr /= 0) then
    1505            0 :             write(*,2) 'mesh_adjust do1_lnT ierr', ierr
    1506            0 :             call mesa_error(__FILE__,__LINE__,'do1_lnT')
    1507              :          end if
    1508              : 
    1509        10623 :       end subroutine do1_lnT
    1510              : 
    1511              : 
    1512         5888 :       subroutine get_old_value_integral( &
    1513         5888 :             k_new, k_old_in, nz_old, xq_old, dq_old, xq_outer, dq_range, &
    1514         5888 :             value_old, integral, dbg, ierr)
    1515              :          integer, intent(in) :: k_new, k_old_in, nz_old
    1516              :          real(dp), intent(in) :: xq_old(:), dq_old(:), xq_outer, dq_range
    1517              :          real(dp), intent(in), dimension(:) :: value_old
    1518              :          real(dp), intent(out) :: integral
    1519              :          logical, intent(in) :: dbg
    1520              :          integer, intent(out) :: ierr
    1521              :          real(dp), pointer :: p(:,:)
    1522              :          nullify(p)
    1523              :          call get_old_integral( &
    1524              :             k_new, k_old_in, nz_old, xq_old, dq_old, xq_outer, dq_range, &
    1525         5888 :             value_old, p, integral, dbg, ierr)
    1526        10623 :       end subroutine get_old_value_integral
    1527              : 
    1528              : 
    1529         5888 :       subroutine get_old_integral( &
    1530         5888 :             k_new, k_old_in, nz_old, xq_old, dq_old, xq_outer, dq_range, &
    1531         5888 :             value_old, xh_old, integral, dbg, ierr)
    1532              :          integer, intent(in) :: k_new, k_old_in, nz_old
    1533              :          real(dp), intent(in) :: xq_old(:), dq_old(:), xq_outer, dq_range
    1534              :          real(dp), intent(in) :: value_old(:)
    1535              :          real(dp), intent(in), pointer :: xh_old(:,:)
    1536              :          real(dp), intent(out) :: integral
    1537              :          logical, intent(in) :: dbg
    1538              :          integer, intent(out) :: ierr
    1539              : 
    1540              :          integer :: k, k_old
    1541         5888 :          real(dp) :: xq_inner, sum_dqs, old_xq_outer, old_xq_inner, &
    1542         5888 :             dq_overlap, val
    1543              : 
    1544              :          include 'formats'
    1545              : 
    1546         5888 :          if (dbg) write(*,*)
    1547              : 
    1548         5888 :          ierr = 0
    1549              : 
    1550         5888 :          k_old = k_old_in
    1551              :          ! move starting k_old if necessary
    1552            0 :          do
    1553         5888 :             if (k_old <= 1) exit
    1554         5888 :             if (xq_old(k_old) <= xq_outer) exit
    1555         5888 :             k_old = k_old - 1
    1556              :          end do
    1557              : 
    1558         5888 :          xq_inner = xq_outer + dq_range
    1559         5888 :          old_xq_inner = xq_old(k_old)
    1560         5888 :          sum_dqs = 0
    1561         5888 :          integral = 0d0
    1562              : 
    1563         5888 :          if (dbg) write(*,*)
    1564         5888 :          if (dbg) write(*,3) 'k_new k_old xq_outer xq_inner dq_range', &
    1565            0 :             k_new, k_old, xq_outer, xq_inner, dq_range
    1566              : 
    1567        17664 :          do k = k_old, nz_old
    1568              : 
    1569        17664 :             if (dq_range <= sum_dqs) exit
    1570        11776 :             old_xq_outer = old_xq_inner
    1571        11776 :             if (k == nz_old) then
    1572            0 :                old_xq_inner = 1
    1573              :             else
    1574        11776 :                old_xq_inner = xq_old(k+1)
    1575              :             end if
    1576              : 
    1577        11776 :             if (dbg) write(*,3) 'k_new k_old old_xq_outer old_xq_inner', &
    1578            0 :                k_new, k, old_xq_outer, old_xq_inner
    1579              : 
    1580        11776 :             val = value_old(k)
    1581              : 
    1582        17664 :             if (old_xq_inner <= xq_inner .and. old_xq_outer >= xq_outer) then
    1583              : 
    1584        11776 :                if (dbg) write(*,1) 'entire old cell is in new range'
    1585              : 
    1586        11776 :                sum_dqs = sum_dqs + dq_old(k)
    1587        11776 :                integral = integral + val*dq_old(k)
    1588              : 
    1589            0 :             else if (old_xq_inner >= xq_inner .and. old_xq_outer <= xq_outer) then
    1590              : 
    1591            0 :                if (dbg) write(*,1) 'entire new range is in this old cell'
    1592              : 
    1593            0 :                sum_dqs = dq_range
    1594            0 :                integral = val*dq_range
    1595              : 
    1596              :             else  ! only use the part of old cell that is in new range
    1597              : 
    1598            0 :                if (xq_inner <= old_xq_inner) then
    1599              : 
    1600            0 :                   if (dbg) write(*,1) 'last part of the new range'
    1601              : 
    1602            0 :                   integral = integral + val*(dq_range - sum_dqs)
    1603            0 :                   sum_dqs = dq_range
    1604              : 
    1605              :                else  ! partial overlap -- general case
    1606              : 
    1607            0 :                   dq_overlap = max(0d0, old_xq_inner - xq_outer)
    1608            0 :                   sum_dqs = sum_dqs + dq_overlap
    1609            0 :                   integral = integral + val*dq_overlap
    1610              : 
    1611            0 :                   if (dbg) write(*,1) 'partial overlap'
    1612              : 
    1613              :                end if
    1614              : 
    1615              :             end if
    1616              : 
    1617              :          end do
    1618              : 
    1619         5888 :          if (dbg) write(*,2) 'integral/dq_range', &
    1620            0 :             k_new, integral/dq_range, integral, dq_range
    1621         5888 :          if (dbg) write(*,*)
    1622              : 
    1623         5888 :       end subroutine get_old_integral
    1624              : 
    1625              : 
    1626         1472 :       subroutine set_lnT_for_energy( &
    1627         1472 :             s, k, h1, he3, he4, species, xa, &
    1628              :             Rho, logRho, energy, lnT_guess, lnT, result_energy, ierr)
    1629              :          type (star_info), pointer :: s
    1630              :          integer, intent(in) :: k, h1, he3, he4, species
    1631              :          real(dp), intent(in) :: xa(species), Rho, logRho, energy, lnT_guess
    1632              :          real(dp), intent(out) :: lnT, result_energy
    1633              :          integer, intent(out) :: ierr
    1634              :          call set_lnT_for_energy_with_tol( &
    1635              :             s, k, h1, he3, he4, species, xa, 1d-11, &
    1636         1472 :             Rho, logRho, energy, lnT_guess, lnT, result_energy, ierr)
    1637            0 :       end subroutine set_lnT_for_energy
    1638              : 
    1639              : 
    1640         1472 :       subroutine set_lnT_for_energy_with_tol( &
    1641         1472 :             s, k, h1, he3, he4, species, xa, tol, &
    1642              :             Rho, logRho, energy, lnT_guess, lnT, result_energy, ierr)
    1643              :          use eos_support, only: solve_eos_given_DE
    1644              :          use eos_def, only: num_eos_basic_results, num_eos_d_dxa_results, i_lnE
    1645              :          use chem_lib, only: basic_composition_info
    1646              :          type (star_info), pointer :: s
    1647              :          integer, intent(in) :: k, h1, he3, he4, species
    1648              :          real(dp), intent(in) :: xa(species), tol, Rho, logRho, energy, lnT_guess
    1649              :          real(dp), intent(out) :: lnT, result_energy
    1650              :          integer, intent(out) :: ierr
    1651              : 
    1652              :          real(dp) :: &
    1653        39744 :             logT, res(num_eos_basic_results), &
    1654        78016 :             d_dlnd(num_eos_basic_results), d_dlnT(num_eos_basic_results), &
    1655        38272 :             d_dxa(num_eos_d_dxa_results, s% species), &
    1656         1472 :             logT_tol, logE_tol
    1657              : 
    1658              :          include 'formats'
    1659              : 
    1660         1472 :          ierr = 0
    1661              : 
    1662         1472 :          logT_tol = tol  ! 1d-11
    1663         1472 :          logE_tol = tol  ! 1d-11
    1664              :          call solve_eos_given_DE( &
    1665              :             s, k, xa(:), &
    1666              :             logRho, log10(energy), lnT_guess/ln10, &
    1667              :             logT_tol, logE_tol, &
    1668              :             logT, res, d_dlnd, d_dlnT, &
    1669              :             d_dxa, &
    1670         1472 :             ierr)
    1671         1472 :          lnT = logT*ln10
    1672              : 
    1673         1472 :          result_energy = exp(res(i_lnE))
    1674              : 
    1675         1472 :          if (ierr /= 0 .or. is_bad_num(lnT)) then
    1676            0 :             ierr = -1
    1677            0 :             if (s% stop_for_bad_nums) then
    1678            0 :                write(*,2) 'lnT', k, lnT
    1679            0 :                call mesa_error(__FILE__,__LINE__,'mesh adjust: do1_lnT')
    1680              :             end if
    1681              :             return
    1682              :          end if
    1683              : 
    1684              :          contains
    1685              : 
    1686              :          subroutine show
    1687              :             include 'formats'
    1688              :             write(*,'(A)')
    1689              :             write(*,*) 'set_lnT_for_energy ierr', ierr
    1690              :             write(*,*) 'k', k
    1691              :             write(*,'(A)')
    1692              :             write(*,1) 'lnT =', lnT
    1693              :             write(*,'(A)')
    1694              :             write(*,1) 'logRho =', logRho
    1695              :             write(*,1) 'logT_guess =', lnT_guess/ln10
    1696              :             write(*,1) 'energy =', energy
    1697              :             write(*,'(A)')
    1698              :             write(*,'(A)')
    1699         1472 :          end subroutine show
    1700              : 
    1701              :       end subroutine set_lnT_for_energy_with_tol
    1702              : 
    1703              : 
    1704              :       ! Stiriba, Youssef, Appl, Numer. Math. 45, 499-511. 2003.
    1705              : 
    1706              :          ! LPP-HARMOD -- local piecewise parabolic reconstruction
    1707              : 
    1708              :          ! interpolant is derived to conserve integral of v in cell k
    1709              :          ! interpolant slope at cell midpoint is harmonic mean of slopes between adjacent cells
    1710              :          ! where these slopes between cells are defined as the difference between cell averages
    1711              :          ! divided by the distance between cell midpoints.
    1712              :          ! interpolant curvature based on difference between the midpoint slope
    1713              :          ! and the smaller in magnitude of the slopes between adjacent cells.
    1714              : 
    1715              :          ! interpolant f(dq) = a + b*dq + (c/2)*dq^2, with dq = q - q_midpoint
    1716              :          ! c0 holds a's, c1 holds b's, and c2 holds c's.
    1717              : 
    1718              : 
    1719        27576 :       subroutine get1_lpp(k, ldv, nz, j, dq, v, quad, c0, c1, c2)
    1720              :          integer, intent(in) :: k, ldv, nz, j
    1721              :          real(dp), intent(in) :: dq(:)  ! (nz)
    1722              :          real(dp), intent(in) :: v(:,:)  ! (ldv,nz)
    1723              :          logical, intent(in) :: quad
    1724              :          real(dp), dimension(:) :: c0, c1, c2
    1725              : 
    1726        27576 :          real(dp) :: vbdy1, vbdy2, dqhalf, sm1, s00, sprod
    1727              :          real(dp), parameter :: rel_curvature_limit = 0.1d0
    1728              : 
    1729              :          logical :: dbg
    1730              : 
    1731              :          include 'formats'
    1732              : 
    1733        27576 :          if (k == 1 .or. k == nz) then
    1734           48 :             call set_const
    1735           48 :             return
    1736              :          end if
    1737              : 
    1738        27528 :          dbg = .false.
    1739              :          !dbg = (k == 30 .and. j == 3) ! .false.
    1740              : 
    1741        27528 :          sm1 = (v(j,k-1) - v(j,k)) / ((dq(k-1) + dq(k))/2)
    1742        27528 :          s00 = (v(j,k) - v(j,k+1)) / ((dq(k) + dq(k+1))/2)
    1743              : 
    1744        27528 :          sprod = sm1*s00
    1745        27528 :          if (sprod <= 0) then
    1746              :             ! at local min or max, so set slope and curvature to 0.
    1747         8218 :             call set_const
    1748         8218 :             return
    1749              :          end if
    1750              : 
    1751        19310 :          if (.not. quad) then
    1752        19310 :             c0(k) = v(j,k)
    1753        19310 :             c1(k) = (sm1 + s00)/2  ! use average to smooth abundance transitions
    1754        19310 :             c2(k) = 0  ! Yan Wang fixed this -- it was left out initially.
    1755              :          else
    1756            0 :             c1(k) = sprod*2/(s00 + sm1)  ! harmonic mean slope
    1757            0 :             if (abs(sm1) <= abs(s00)) then
    1758            0 :                c2(k) = (sm1 - c1(k))/(2*dq(k))
    1759              :             else
    1760            0 :                c2(k) = (c1(k) - s00)/(2*dq(k))
    1761              :             end if
    1762            0 :             c0(k) = v(j,k) - c2(k)*dq(k)*dq(k)/24
    1763              :          end if
    1764              : 
    1765              :          ! check values at edges for monotonicity
    1766        19310 :          dqhalf = dq(k)/2
    1767        19310 :          vbdy1 = c0(k) + c1(k)*dqhalf + c2(k)/2*dqhalf*dqhalf  ! value at face(k)
    1768        19310 :          vbdy2 = c0(k) - c1(k)*dqhalf + c2(k)/2*dqhalf*dqhalf  ! value at face(k+1)
    1769        19310 :          if ((v(j,k-1) - vbdy1)*(vbdy1 - v(j,k)) < 0 .or. &
    1770              :              (v(j,k) - vbdy2)*(vbdy2 - v(j,k+1)) < 0) then
    1771              :             if (dbg) then
    1772              :                write(*,*) 'non-monotonic'
    1773              :                write(*,2) 'v(j,k-1)', k-1, v(j,k-1)
    1774              :                write(*,2) 'vbdy1', k, vbdy1
    1775              :                write(*,2) 'v(j,k)', k, v(j,k)
    1776              :                write(*,2) 'vbdy2', k, vbdy2
    1777              :                write(*,2) 'v(j,k+1)', k+1, v(j,k+1)
    1778              :                write(*,'(A)')
    1779              :                write(*,2) 'v(j,k-1) - vbdy1', k, v(j,k-1) - vbdy1
    1780              :                write(*,2) 'vbdy1 - v(j,k+1)', k, vbdy1 - v(j,k+1)
    1781              :                write(*,'(A)')
    1782              :                write(*,2) 'v(j,k-1) - vbdy2', k, v(j,k-1) - vbdy2
    1783              :                write(*,2) 'vbdy2 - v(j,k+1)', k, vbdy2 - v(j,k+1)
    1784              :                write(*,'(A)')
    1785              :                write(*,2) 'sm1', k, sm1
    1786              :                write(*,2) 's00', k, s00
    1787              :                write(*,'(A)')
    1788              :                call mesa_error(__FILE__,__LINE__,'debug: get1_lpp')
    1789              :             end if
    1790          160 :             c2(k) = 0
    1791          160 :             if (abs(sm1) <= abs(s00)) then
    1792           84 :                c1(k) = sm1
    1793              :             else
    1794           76 :                c1(k) = s00
    1795              :             end if
    1796              :          end if
    1797              : 
    1798              :          contains
    1799              : 
    1800         8266 :          subroutine set_const
    1801         8266 :             c0(k) = v(j,k)
    1802         8266 :             c1(k) = 0
    1803         8266 :             if (quad) c2(k) = 0
    1804         8266 :          end subroutine set_const
    1805              : 
    1806              :       end subroutine get1_lpp
    1807              : 
    1808              : 
    1809        11776 :       subroutine get_xq_integral( &
    1810        11776 :             k_old_in, nz_old, xq_old, xq_outer, dq, &
    1811        11776 :             order, c0, c1, c2, integral, dbg, k_old_last, ierr)
    1812              :          ! integrate val(j,:) from xq_inner to xq_outer, with xq_inner = xq_outer + dq
    1813              :          integer, intent(in) :: k_old_in, nz_old
    1814              :          real(dp), intent(in) :: xq_old(:), xq_outer, dq
    1815              :          integer, intent(in) :: order  ! 0, 1, 2
    1816              :          real(dp), intent(in), dimension(:) :: c0, c1, c2  ! coefficients
    1817              :          real(dp), intent(out) :: integral
    1818              :          logical, intent(in) :: dbg
    1819              :          integer, intent(out) :: k_old_last, ierr
    1820              : 
    1821              :          integer :: k, k_old
    1822        11776 :          real(dp) :: a, b, c, old_xq_inner, old_xq_outer, xq_inner, &
    1823        11776 :             xq_overlap_outer, xq_overlap_inner, dq1, sum_dqs, old_xq_mid, &
    1824        11776 :             v_overlap_outer, v_overlap_inner, dq_outer, dq_inner, avg_value
    1825              : 
    1826              :          include 'formats'
    1827              : 
    1828        11776 :          if (dbg) write(*,*)
    1829              : 
    1830        11776 :          ierr = 0
    1831        11776 :          k_old = k_old_in
    1832              :          ! move starting k_old if necessary
    1833            0 :          do
    1834        11776 :             if (k_old <= 1) exit
    1835        11776 :             if (xq_old(k_old) <= xq_outer) exit
    1836        11776 :             k_old = k_old - 1
    1837              :          end do
    1838        11776 :          xq_inner = xq_outer + dq
    1839        11776 :          old_xq_inner = xq_old(k_old)
    1840        11776 :          sum_dqs = 0
    1841        11776 :          integral = 0d0
    1842              : 
    1843        35328 :          do k = k_old, nz_old
    1844        35328 :             if (dq <= sum_dqs) exit
    1845        35328 :             old_xq_outer = old_xq_inner
    1846        35328 :             if (k == nz_old) then
    1847            0 :                old_xq_inner = 1
    1848              :             else
    1849        35328 :                old_xq_inner = xq_old(k+1)
    1850              :             end if
    1851        35328 :             xq_overlap_outer = max(xq_outer, old_xq_outer)
    1852        35328 :             xq_overlap_inner = min(xq_inner, old_xq_inner)
    1853              : 
    1854        35328 :             if (dbg) then
    1855            0 :                write(*,2) 'xq_overlap_outer', k, xq_overlap_outer
    1856            0 :                write(*,2) 'xq_outer', k, xq_outer
    1857            0 :                write(*,2) 'old_xq_outer', k, old_xq_outer
    1858            0 :                write(*,2) 'xq_overlap_inner', k, xq_overlap_inner
    1859            0 :                write(*,2) 'xq_inner', k, xq_inner
    1860            0 :                write(*,2) 'old_xq_inner', k, old_xq_inner
    1861              :             end if
    1862              : 
    1863        35328 :             if (sum_dqs == 0 .and. xq_overlap_outer == xq_outer .and.  &
    1864              :                xq_overlap_inner == xq_inner) then
    1865              :                ! fully contained
    1866            0 :                xq_inner = xq_outer + dq
    1867            0 :                xq_overlap_inner = xq_inner
    1868            0 :                dq1 = dq
    1869        35328 :             else if (old_xq_inner >= xq_inner) then  ! this is the last one
    1870        11776 :                dq1 = dq - sum_dqs
    1871              :             else
    1872        23552 :                dq1 = max(0d0, xq_overlap_inner-xq_overlap_outer)
    1873              :             end if
    1874        35328 :             sum_dqs = sum_dqs + dq1
    1875              :             ! interpolant f(dq) = a + b*dq + (c/2)*dq^2, with dq = q - q_midpoint
    1876        35328 :             a = c0(k)
    1877        35328 :             b = c1(k)
    1878        35328 :             if (order == 2) then
    1879        35328 :                c = c2(k)
    1880              :             else
    1881            0 :                c = 0
    1882              :             end if
    1883              : 
    1884        35328 :             if (dq1 == 0 .or. (b==0 .and. c==0)) then
    1885        17203 :                avg_value = a
    1886              :             else
    1887        18125 :                old_xq_mid = (old_xq_outer + old_xq_inner)/2
    1888        18125 :                dq_outer = old_xq_mid - xq_overlap_outer
    1889        18125 :                dq_inner = old_xq_mid - xq_overlap_inner
    1890              : 
    1891        18125 :                if (order == 0) then
    1892            0 :                   avg_value = a
    1893        18125 :                else if (order == 1 .or. c == 0) then
    1894              :                   ! use slope to estimate average value in the region being used
    1895        18125 :                   if (dbg) write(*,*) 'use slope to estimate average value'
    1896        18125 :                   v_overlap_outer = a + dq_outer*b
    1897        18125 :                   v_overlap_inner = a + dq_inner*b
    1898        18125 :                   avg_value = (v_overlap_outer + v_overlap_inner)/2
    1899              :                else  ! use quadratic reconstruction
    1900            0 :                   if (dbg) write(*,*) 'use quadratic reconstruction'
    1901              :                   avg_value = &
    1902              :                      a + b*(dq_inner + dq_outer)/2 + &
    1903            0 :                         c*(dq_inner*dq_inner + dq_inner*dq_outer + dq_outer*dq_outer)/6
    1904              :                end if
    1905              :             end if
    1906        35328 :             integral = integral + dq1*avg_value
    1907        35328 :             if (dbg) then
    1908            0 :                write(*,2) 'a', k, a
    1909            0 :                write(*,2) 'b', k, b
    1910            0 :                write(*,2) 'c', k, c
    1911            0 :                write(*,2) 'dq1', k, dq1
    1912            0 :                write(*,2) 'avg_value', k, avg_value
    1913            0 :                write(*,2) 'integral', k, integral
    1914            0 :                write(*,'(A)')
    1915              :             end if
    1916        35328 :             k_old_last = k
    1917        35328 :             if (old_xq_inner >= xq_inner) exit  ! this is the last one
    1918              : 
    1919              :          end do
    1920              : 
    1921        11776 :          if (dbg) write(*,1) 'integral/dq', integral/dq, integral, dq
    1922              : 
    1923        11776 :       end subroutine get_xq_integral
    1924              : 
    1925              : 
    1926            0 :       subroutine adjust_omega(s, nz, nz_old, comes_from, &
    1927            0 :             old_xq, new_xq, old_dq, new_dq, xh, old_j_rot, &
    1928            0 :             xout_old, xout_new, old_dqbar, new_dqbar, ierr)
    1929              :          use alloc
    1930              :          type (star_info), pointer :: s
    1931              :          integer, intent(in) :: nz, nz_old
    1932              :          integer, dimension(:) :: comes_from
    1933              :          real(dp), dimension(:) :: &
    1934              :             old_xq, new_xq, old_dq, new_dq, old_j_rot, &
    1935              :             xout_old, xout_new, old_dqbar, new_dqbar
    1936              :          real(dp), intent(in) :: xh(:,:)
    1937              :          integer, intent(out) :: ierr
    1938              :          integer :: k, op_err
    1939              :          include 'formats'
    1940            0 :          ierr = 0
    1941              : 
    1942            0 : !$OMP PARALLEL DO PRIVATE(k, op_err) SCHEDULE(dynamic,2)
    1943              :          do k = 1, nz
    1944              :             op_err = 0
    1945              :             call adjust1_omega(s, k, nz, nz_old, comes_from, &
    1946              :                xout_old, xout_new, old_dqbar, new_dqbar, old_j_rot, xh, op_err)
    1947              :             if (op_err /= 0) ierr = op_err
    1948              :          end do
    1949              : !$OMP END PARALLEL DO
    1950              : 
    1951            0 :       end subroutine adjust_omega
    1952              : 
    1953              : 
    1954            0 :       subroutine adjust1_omega(s, k, nz, nz_old, comes_from, &
    1955            0 :             xout_old, xout_new, old_dqbar, new_dqbar, old_j_rot, xh, ierr)
    1956            0 :          use hydro_rotation, only: w_div_w_roche_jrot, update1_i_rot_from_xh
    1957              :          ! set new value for s% omega(k)
    1958              :          type (star_info), pointer :: s
    1959              :          integer, intent(in) :: k, nz, nz_old
    1960              :          integer, dimension(:) :: comes_from
    1961              :          real(dp), dimension(:), intent(in) :: &
    1962              :             xout_old, xout_new, old_dqbar, new_dqbar, old_j_rot
    1963              :          real(dp), intent(in) :: xh(:,:)
    1964              :          integer, intent(out) :: ierr
    1965              : 
    1966            0 :          real(dp) :: xq_outer, xq_inner, j_tot, xq0, xq1, new_point_dqbar, dq_sum, dq, r00
    1967              :          integer :: kk, k_outer
    1968              : 
    1969              :          integer, parameter :: k_dbg = -1
    1970              : 
    1971              :          include 'formats'
    1972              : 
    1973            0 :          ierr = 0
    1974            0 :          xq_outer = xout_new(k)
    1975            0 :          new_point_dqbar = new_dqbar(k)
    1976            0 :          if (k < nz) then
    1977            0 :             xq_inner = xq_outer + new_point_dqbar
    1978              :          else
    1979            0 :             xq_inner = 1d0
    1980              :          end if
    1981              : 
    1982            0 :          if (k == k_dbg) then
    1983            0 :             write(*,2) 'xq_outer', k, xq_outer
    1984            0 :             write(*,2) 'xq_inner', k, xq_inner
    1985            0 :             write(*,2) 'new_point_dqbar', k, new_point_dqbar
    1986              :          end if
    1987              : 
    1988            0 :          dq_sum = 0d0
    1989            0 :          j_tot = 0
    1990            0 :          if (xq_outer >= xout_old(nz_old)) then
    1991              :             ! new contained entirely in old center zone
    1992            0 :             k_outer = nz_old
    1993            0 :             if (k == k_dbg) &
    1994            0 :                write(*,2) 'new contained in old center', &
    1995            0 :                   k_outer, xout_old(k_outer)
    1996            0 :          else if (k == 1) then
    1997            0 :             k_outer = 1
    1998              :          else
    1999            0 :             k_outer = comes_from(k-1)
    2000              :          end if
    2001              : 
    2002            0 :          do kk = k_outer, nz_old  ! loop until reach m_inner
    2003              : 
    2004            0 :             if (kk == nz_old) then
    2005            0 :                xq1 = 1d0
    2006              :             else
    2007            0 :                xq1 = xout_old(kk+1)
    2008              :             end if
    2009            0 :             if (xq1 <= xq_outer) cycle
    2010              : 
    2011            0 :             xq0 = xout_old(kk)
    2012            0 :             if (xq0 >= xq_inner) then
    2013            0 :                if (dq_sum < new_point_dqbar .and. kk > 1) then
    2014              :                   ! need to add a bit more from the previous source
    2015            0 :                   dq = new_point_dqbar - dq_sum
    2016            0 :                   dq_sum = new_point_dqbar
    2017            0 :                   j_tot = j_tot + old_j_rot(kk-1)*dq
    2018              :                   end if
    2019              :                exit
    2020              :             end if
    2021              : 
    2022            0 :             if (xq1 < xq_outer) then
    2023            0 :                ierr = -1
    2024            0 :                return
    2025              :             end if
    2026              : 
    2027            0 :             if (xq0 >= xq_outer .and. xq1 <= xq_inner) then  ! entire old kk is in new k
    2028              : 
    2029            0 :                dq = old_dqbar(kk)
    2030            0 :                dq_sum = dq_sum + dq
    2031              : 
    2032            0 :                if (dq_sum > new_point_dqbar) then
    2033              :                   ! dq too large -- numerical roundoff problems
    2034            0 :                   dq = dq - (new_point_dqbar - dq_sum)
    2035            0 :                   dq_sum = new_point_dqbar
    2036              :                end if
    2037              : 
    2038            0 :                j_tot = j_tot + old_j_rot(kk)*dq
    2039              : 
    2040            0 :             else if (xq0 <= xq_outer .and. xq1 >= xq_inner) then  ! entire new k is in old kk
    2041              : 
    2042            0 :                dq = new_dqbar(k)
    2043            0 :                dq_sum = dq_sum + dq
    2044            0 :                j_tot = j_tot + old_j_rot(kk)*dq
    2045              : 
    2046              :             else  ! only use the part of old kk that is in new k
    2047              : 
    2048            0 :                if (k == k_dbg) then
    2049            0 :                   write(*,*) 'only use the part of old kk that is in new k', xq_inner <= xq1
    2050            0 :                   write(*,1) 'xq_outer', xq_outer
    2051            0 :                   write(*,1) 'xq_inner', xq_inner
    2052            0 :                   write(*,1) 'xq0', xq0
    2053            0 :                   write(*,1) 'xq1', xq1
    2054            0 :                   write(*,1) 'dq_sum', dq_sum
    2055            0 :                   write(*,1) 'new_point_dqbar', new_point_dqbar
    2056            0 :                   write(*,1) 'new_point_dqbar - dq_sum', new_point_dqbar - dq_sum
    2057              :                end if
    2058              : 
    2059            0 :                if (xq_inner <= xq1) then  ! this is the last part of new k
    2060              : 
    2061            0 :                   if (k == k_dbg) write(*,3) 'this is the last part of new k', k, kk
    2062              : 
    2063            0 :                   dq = new_point_dqbar - dq_sum
    2064            0 :                   dq_sum = new_point_dqbar
    2065              : 
    2066              :                else  ! we avoid this case if possible because of numerical roundoff
    2067              : 
    2068            0 :                   if (k == k_dbg) write(*,3) 'we avoid this case if possible', k, kk
    2069              : 
    2070            0 :                   dq = max(0d0, xq1 - xq_outer)
    2071            0 :                   if (dq_sum + dq > new_point_dqbar) dq = new_point_dqbar - dq_sum
    2072            0 :                   dq_sum = dq_sum + dq
    2073              : 
    2074              :                end if
    2075              : 
    2076            0 :                j_tot = j_tot + old_j_rot(kk)*dq
    2077              : 
    2078            0 :                if (dq <= 0) then
    2079            0 :                   ierr = -1
    2080            0 :                   return
    2081              :                end if
    2082              : 
    2083              :             end if
    2084              : 
    2085            0 :             if (dq_sum >= new_point_dqbar) then
    2086            0 :                if (k == k_dbg) then
    2087            0 :                   write(*,2) 'exit for k', k
    2088            0 :                   write(*,2) 'dq_sum', kk, dq_sum
    2089            0 :                   write(*,2) 'new_point_dqbar', kk, new_point_dqbar
    2090              :                end if
    2091              :                exit
    2092              :             end if
    2093              : 
    2094              :          end do
    2095              : 
    2096            0 :          s% j_rot(k) = j_tot/dq_sum
    2097            0 :          r00 = get_r_from_xh(s,k)
    2098              :          s% w_div_w_crit_roche(k) = &
    2099              :             w_div_w_roche_jrot(r00,s% m(k),s% j_rot(k),s% cgrav(k), &
    2100            0 :             s% w_div_wcrit_max, s% w_div_wcrit_max2, s% w_div_wc_flag)
    2101            0 :          call update1_i_rot_from_xh(s, k)
    2102            0 :          s% omega(k) = s% j_rot(k)/s% i_rot(k)% val
    2103              : 
    2104            0 :          if (k_dbg == k) then
    2105            0 :             write(*,2) 's% omega(k)', k, s% omega(k)
    2106            0 :             write(*,2) 's% j_rot(k)', k, s% j_rot(k)
    2107            0 :             write(*,2) 's% i_rot(k)', k, s% i_rot(k)
    2108            0 :             if (s% model_number > 1925) call mesa_error(__FILE__,__LINE__,'debugging: adjust1_omega')
    2109              :          end if
    2110              : 
    2111            0 :       end subroutine adjust1_omega
    2112              : 
    2113              : 
    2114              :       ! like adjust_omega.  conserve kinetic energy
    2115            0 :       subroutine do_v( &
    2116            0 :             s, nz, nz_old, cell_type, comes_from, &
    2117            0 :             old_xq, new_xq, old_dq, new_dq, xh, xh_old, &
    2118            0 :             xout_old, xout_new, old_dqbar, new_dqbar, old_ke, ierr)
    2119            0 :          use alloc
    2120              :          type (star_info), pointer :: s
    2121              :          integer, intent(in) :: nz, nz_old
    2122              :          integer, dimension(:) :: cell_type, comes_from
    2123              :          real(dp), dimension(:) :: &
    2124              :             xout_old, xout_new, old_dqbar, new_dqbar, &
    2125              :             old_xq, new_xq, old_dq, new_dq, old_ke
    2126              :          real(dp), dimension(:,:) :: xh, xh_old
    2127              :          integer, intent(out) :: ierr
    2128              : 
    2129              :          integer :: k, op_err, i_v
    2130            0 :          real(dp) :: old_ke_tot, new_ke_tot, xmstar, err
    2131              : 
    2132              :          include 'formats'
    2133            0 :          ierr = 0
    2134            0 :          i_v = s% i_v
    2135            0 :          xmstar = s% xmstar
    2136              : 
    2137            0 :          old_ke_tot = 0d0
    2138            0 :          do k=1,nz_old  ! skip common factor 1/2 xmstar in ke
    2139            0 :             old_ke(k) = old_dqbar(k)*xh_old(i_v,k)*xh_old(i_v,k)
    2140            0 :             old_ke_tot = old_ke_tot + old_ke(k)
    2141              :          end do
    2142              : 
    2143            0 : !$OMP PARALLEL DO PRIVATE(k,op_err) SCHEDULE(dynamic,2)
    2144              :          do k = 1, nz
    2145              :             op_err = 0
    2146              :             call adjust1_v( &
    2147              :                s, k, nz, nz_old, cell_type, comes_from, xout_old, xout_new, &
    2148              :                old_dqbar, new_dqbar, old_ke, i_v, xh, xh_old, op_err)
    2149              :             if (op_err /= 0) ierr = op_err
    2150              :          end do
    2151              : !$OMP END PARALLEL DO
    2152            0 :          if (ierr /= 0) then
    2153              :             return
    2154              :          end if
    2155              : 
    2156            0 :          new_ke_tot = 0
    2157            0 :          do k=1,nz
    2158            0 :             new_ke_tot = new_ke_tot + new_dqbar(k)*xh(i_v,k)*xh(i_v,k)
    2159              :          end do
    2160              : 
    2161            0 :          if (abs(old_ke_tot - new_ke_tot) > 1d-7*new_ke_tot) then
    2162            0 :             ierr = -1
    2163            0 :             s% retry_message = 'failed in mesh_adjust do_v'
    2164            0 :             if (s% report_ierr) write(*, *) s% retry_message
    2165              :             !call mesa_error(__FILE__,__LINE__,'do_v')
    2166            0 :             return
    2167              :          end if
    2168              : 
    2169            0 :          err = abs(old_ke_tot - new_ke_tot)/max(new_ke_tot,old_ke_tot,1d0)
    2170            0 :          s% mesh_adjust_KE_conservation = err
    2171              : 
    2172            0 :          if (s% trace_mesh_adjust_error_in_conservation) then
    2173            0 :             write(*,2) 'mesh adjust error in conservation of KE', s% model_number, &
    2174            0 :                err, new_ke_tot, old_ke_tot
    2175            0 :             if (err > 1d-10) then
    2176            0 :                write(*,*) 'err too large'
    2177            0 :                call mesa_error(__FILE__,__LINE__,'do_v')
    2178              :             end if
    2179              :          end if
    2180              : 
    2181            0 :       end subroutine do_v
    2182              : 
    2183              : 
    2184            0 :       subroutine adjust1_v( &
    2185            0 :             s, k, nz, nz_old, cell_type, comes_from, xout_old, xout_new, &
    2186            0 :             old_dqbar, new_dqbar, old_ke, i_v, xh, xh_old, ierr)
    2187              :          ! set new value for s% v(k) to conserve kinetic energy
    2188              :          type (star_info), pointer :: s
    2189              :          integer, intent(in) :: k, nz, nz_old, i_v
    2190              :          integer, dimension(:) :: cell_type, comes_from
    2191              :          real(dp), dimension(:), intent(in) :: &
    2192              :             xout_old, xout_new, old_dqbar, new_dqbar, old_ke
    2193              :          real(dp), dimension(:,:) :: xh, xh_old
    2194              :          integer, intent(out) :: ierr
    2195              : 
    2196            0 :          real(dp) :: xq_outer, xq_inner, ke_sum, &
    2197            0 :             xq0, xq1, new_point_dqbar, dq_sum, dq
    2198              :          integer :: kk, k_outer
    2199              : 
    2200              :          integer, parameter :: k_dbg = -1
    2201              : 
    2202              :          include 'formats'
    2203              : 
    2204            0 :          ierr = 0
    2205              : 
    2206            0 :          if (cell_type(k) == unchanged_type .or. &
    2207              :                cell_type(k) == revised_type) then
    2208            0 :             if (k == 1) then
    2209            0 :                xh(i_v,k) = xh_old(i_v,comes_from(k))
    2210            0 :                return
    2211              :             end if
    2212            0 :             if (cell_type(k-1) == unchanged_type) then
    2213            0 :                xh(i_v,k) = xh_old(i_v,comes_from(k))
    2214            0 :                return
    2215              :             end if
    2216              :          end if
    2217              : 
    2218            0 :          xq_outer = xout_new(k)
    2219            0 :          new_point_dqbar = new_dqbar(k)
    2220            0 :          if (k < nz) then
    2221            0 :             xq_inner = xq_outer + new_point_dqbar
    2222              :          else
    2223            0 :             xq_inner = 1d0
    2224              :          end if
    2225              : 
    2226            0 :          if (k == k_dbg) then
    2227            0 :             write(*,2) 'xq_outer', k, xq_outer
    2228            0 :             write(*,2) 'xq_inner', k, xq_inner
    2229            0 :             write(*,2) 'new_point_dqbar', k, new_point_dqbar
    2230              :          end if
    2231              : 
    2232            0 :          dq_sum = 0d0
    2233            0 :          ke_sum = 0
    2234            0 :          if (xq_outer >= xout_old(nz_old)) then
    2235              :             ! new contained entirely in old center zone
    2236            0 :             k_outer = nz_old
    2237            0 :             if (k == k_dbg) &
    2238            0 :                write(*,2) 'new contained in old center', &
    2239            0 :                   k_outer, xout_old(k_outer)
    2240            0 :          else if (k == 1) then
    2241            0 :             k_outer = 1
    2242              :          else
    2243            0 :             k_outer = comes_from(k-1)
    2244              :          end if
    2245              : 
    2246            0 :          do kk = k_outer, nz_old  ! loop until reach xq_inner
    2247              : 
    2248            0 :             if (kk == nz_old) then
    2249            0 :                xq1 = 1d0
    2250              :             else
    2251            0 :                xq1 = xout_old(kk+1)
    2252              :             end if
    2253            0 :             if (xq1 <= xq_outer) cycle
    2254              : 
    2255            0 :             xq0 = xout_old(kk)
    2256            0 :             if (xq0 >= xq_inner) then
    2257            0 :                if (dq_sum < new_point_dqbar .and. kk > 1) then
    2258              :                   ! need to add a bit more from the previous source
    2259            0 :                   dq = new_point_dqbar - dq_sum
    2260            0 :                   dq_sum = new_point_dqbar
    2261            0 :                   ke_sum = ke_sum + old_ke(kk-1)*dq/old_dqbar(kk-1)
    2262              : 
    2263            0 :                   if (k == k_dbg) &
    2264            0 :                      write(*,3) 'new k contains some of old kk-1', &
    2265            0 :                         k, kk, old_ke(kk-1)*dq, dq_sum
    2266              : 
    2267              :                   end if
    2268              :                exit
    2269              :             end if
    2270              : 
    2271            0 :             if (xq1 < xq_outer) then
    2272            0 :                ierr = -1
    2273            0 :                return
    2274              :             end if
    2275              : 
    2276            0 :             if (xq0 >= xq_outer .and. xq1 <= xq_inner) then  ! entire old kk is in new k
    2277              : 
    2278            0 :                dq = old_dqbar(kk)
    2279            0 :                dq_sum = dq_sum + dq
    2280              : 
    2281            0 :                if (dq_sum > new_point_dqbar) then
    2282              :                   ! dq too large -- numerical roundoff problems
    2283            0 :                   dq = dq - (new_point_dqbar - dq_sum)
    2284            0 :                   dq_sum = new_point_dqbar
    2285              :                end if
    2286              : 
    2287            0 :                ke_sum = ke_sum + old_ke(kk)*dq/old_dqbar(kk)
    2288              : 
    2289            0 :                if (k == k_dbg) &
    2290            0 :                   write(*,3) 'new k contains all of old kk', &
    2291            0 :                      k, kk, old_ke(kk)*dq, ke_sum
    2292              : 
    2293            0 :             else if (xq0 <= xq_outer .and. xq1 >= xq_inner) then  ! entire new k is in old kk
    2294              : 
    2295            0 :                dq = new_dqbar(k)
    2296            0 :                dq_sum = dq_sum + dq
    2297            0 :                ke_sum = ke_sum + old_ke(kk)*dq/old_dqbar(kk)
    2298              : 
    2299            0 :                if (k == k_dbg) &
    2300            0 :                   write(*,3) 'all new k is in old kk', &
    2301            0 :                      k, kk, old_ke(kk)*dq, ke_sum
    2302              : 
    2303              :             else  ! only use the part of old kk that is in new k
    2304              : 
    2305            0 :                if (k == k_dbg) then
    2306            0 :                   write(*,*) 'only use the part of old kk that is in new k', xq_inner <= xq1
    2307            0 :                   write(*,1) 'xq_outer', xq_outer
    2308            0 :                   write(*,1) 'xq_inner', xq_inner
    2309            0 :                   write(*,1) 'xq0', xq0
    2310            0 :                   write(*,1) 'xq1', xq1
    2311            0 :                   write(*,1) 'dq_sum', dq_sum
    2312            0 :                   write(*,1) 'new_point_dqbar', new_point_dqbar
    2313            0 :                   write(*,1) 'new_point_dqbar - dq_sum', new_point_dqbar - dq_sum
    2314              :                end if
    2315              : 
    2316            0 :                if (xq_inner <= xq1) then  ! this is the last part of new k
    2317              : 
    2318            0 :                   dq = new_point_dqbar - dq_sum
    2319            0 :                   dq_sum = new_point_dqbar
    2320              : 
    2321              :                else  ! we avoid this case if possible because of numerical roundoff
    2322              : 
    2323            0 :                   if (k == k_dbg) write(*,3) 'we avoid this case if possible', k, kk
    2324              : 
    2325            0 :                   dq = max(0d0, xq1 - xq_outer)
    2326            0 :                   if (dq_sum + dq > new_point_dqbar) dq = new_point_dqbar - dq_sum
    2327            0 :                   dq_sum = dq_sum + dq
    2328              : 
    2329              :                end if
    2330              : 
    2331            0 :                if (k == k_dbg) then
    2332            0 :                   write(*,3) 'new k use only part of old kk', k, kk
    2333            0 :                   write(*,2) 'dq_sum', k, dq_sum
    2334            0 :                   write(*,2) 'dq', k, dq
    2335            0 :                   write(*,2) 'old_ke(kk)', kk, old_ke(kk)
    2336            0 :                   write(*,2) 'old ke_sum', k, ke_sum
    2337            0 :                   write(*,2) 'new ke_sum', k, ke_sum + old_ke(kk)*dq
    2338              :                end if
    2339              : 
    2340            0 :                ke_sum = ke_sum + old_ke(kk)*dq/old_dqbar(kk)
    2341              : 
    2342            0 :                if (dq <= 0) then
    2343            0 :                   ierr = -1
    2344              :                   !return
    2345            0 :                   write(*,*) 'dq <= 0', dq
    2346            0 :                   call mesa_error(__FILE__,__LINE__,'debugging: adjust1_v')
    2347              :                end if
    2348              : 
    2349              :             end if
    2350              : 
    2351            0 :             if (dq_sum >= new_point_dqbar) then
    2352              :                exit
    2353              :             end if
    2354              : 
    2355              :          end do
    2356              : 
    2357            0 :          xh(i_v,k) = sqrt(ke_sum/new_point_dqbar)  ! we have skipped the 1/2 xmstar factor
    2358            0 :          if (xh_old(i_v,comes_from(k)) < 0d0) xh(i_v,k) = -xh(i_v,k)
    2359              : 
    2360            0 :          if (k == k_dbg) then
    2361            0 : !$OMP critical (adjust1_v_dbg)
    2362            0 :             write(*,2) 'xh(i_v,k) new_dqbar', k, xh(i_v,k), new_dqbar(k)
    2363            0 :             write(*,2) 'xh_old(i_v,comes_from(k)) old_dqbar', &
    2364            0 :                comes_from(k), xh_old(i_v,comes_from(k)), old_dqbar(comes_from(k))
    2365            0 :             if (k == k_dbg) call mesa_error(__FILE__,__LINE__,'adjust1_v')
    2366              : !$OMP end critical (adjust1_v_dbg)
    2367              :             !stop
    2368              :          end if
    2369              : 
    2370            0 :       end subroutine adjust1_v
    2371              : 
    2372              : 
    2373            0 :       subroutine do_u( &
    2374            0 :             s, nz, nz_old, cell_type, comes_from, &
    2375            0 :             old_xq, new_xq, old_dq, new_dq, xh, xh_old, &
    2376            0 :             xout_old, xout_new, old_ke, ierr)
    2377              :          use alloc
    2378              :          type (star_info), pointer :: s
    2379              :          integer, intent(in) :: nz, nz_old
    2380              :          integer, dimension(:) :: cell_type, comes_from
    2381              :          real(dp), dimension(:) :: &
    2382              :             xout_old, xout_new, old_xq, new_xq, old_dq, new_dq, old_ke
    2383              :          real(dp), dimension(:,:) :: xh, xh_old
    2384              :          integer, intent(out) :: ierr
    2385              : 
    2386              :          integer :: k, op_err, i_u
    2387            0 :          real(dp) :: old_ke_tot, new_ke_tot, xmstar, err
    2388              : 
    2389              :          include 'formats'
    2390            0 :          ierr = 0
    2391            0 :          i_u = s% i_u
    2392            0 :          xmstar = s% xmstar
    2393              : 
    2394            0 :          old_ke_tot = 0d0
    2395            0 :          do k=1,nz_old  ! skip common factor 1/2 xmstar in ke
    2396            0 :             old_ke(k) = old_dq(k)*xh_old(i_u,k)*xh_old(i_u,k)
    2397            0 :             old_ke_tot = old_ke_tot + old_ke(k)
    2398              :          end do
    2399              : 
    2400            0 : !$OMP PARALLEL DO PRIVATE(k,op_err) SCHEDULE(dynamic,2)
    2401              :          do k = 1, nz
    2402              :             op_err = 0
    2403              :             call adjust1_u( &
    2404              :                s, k, nz, nz_old, cell_type, comes_from, xout_old, xout_new, &
    2405              :                old_dq, new_dq, old_ke, i_u, xh, xh_old, op_err)
    2406              :             if (op_err /= 0) ierr = op_err
    2407              :          end do
    2408              : !$OMP END PARALLEL DO
    2409            0 :          if (ierr /= 0) then
    2410              :             return
    2411              :          end if
    2412              : 
    2413            0 :          new_ke_tot = 0
    2414            0 :          do k=1,nz
    2415            0 :             new_ke_tot = new_ke_tot + new_dq(k)*xh(i_u,k)*xh(i_u,k)
    2416              :          end do
    2417              : 
    2418            0 :          err = abs(old_ke_tot - new_ke_tot)/max(new_ke_tot,old_ke_tot,1d0)
    2419            0 :          s% mesh_adjust_KE_conservation = err
    2420              : 
    2421            0 :          if (s% trace_mesh_adjust_error_in_conservation) then
    2422            0 :             write(*,2) 'mesh adjust error in conservation of KE', s% model_number, &
    2423            0 :                err, new_ke_tot, old_ke_tot
    2424            0 :             if (err > 1d-10) then
    2425            0 :                write(*,*) 'err too large'
    2426            0 :                call mesa_error(__FILE__,__LINE__,'do_u')
    2427              :             end if
    2428              :          end if
    2429              : 
    2430            0 :       end subroutine do_u
    2431              : 
    2432              : 
    2433            0 :       subroutine adjust1_u( &
    2434            0 :             s, k, nz, nz_old, cell_type, comes_from, xout_old, xout_new, &
    2435            0 :             old_dq, new_dq, old_ke, i_u, xh, xh_old, ierr)
    2436              :          ! set new value for s% u(k) to conserve kinetic energy
    2437              :          type (star_info), pointer :: s
    2438              :          integer, intent(in) :: k, nz, nz_old, i_u
    2439              :          integer, dimension(:) :: cell_type, comes_from
    2440              :          real(dp), dimension(:), intent(in) :: &
    2441              :             xout_old, xout_new, old_dq, new_dq, old_ke
    2442              :          real(dp), dimension(:,:) :: xh, xh_old
    2443              :          integer, intent(out) :: ierr
    2444              : 
    2445            0 :          real(dp) :: xq_outer, xq_inner, ke_sum, &
    2446            0 :             xq0, xq1, new_cell_dq, dq_sum, dq
    2447              :          integer :: kk, k_outer
    2448              : 
    2449              :          integer, parameter :: k_dbg = -1
    2450              : 
    2451              :          include 'formats'
    2452              : 
    2453            0 :          ierr = 0
    2454              : 
    2455            0 :          if (cell_type(k) == unchanged_type .or. &
    2456              :                cell_type(k) == revised_type) then
    2457            0 :             if (k == 1) then
    2458            0 :                xh(i_u,k) = xh_old(i_u,comes_from(k))
    2459            0 :                return
    2460              :             end if
    2461            0 :             if (cell_type(k-1) == unchanged_type) then
    2462            0 :                xh(i_u,k) = xh_old(i_u,comes_from(k))
    2463            0 :                return
    2464              :             end if
    2465              :          end if
    2466              : 
    2467            0 :          xq_outer = xout_new(k)
    2468            0 :          new_cell_dq = new_dq(k)
    2469            0 :          if (k < nz) then
    2470            0 :             xq_inner = xq_outer + new_cell_dq
    2471              :          else
    2472            0 :             xq_inner = 1d0
    2473              :          end if
    2474              : 
    2475            0 :          if (k == k_dbg) then
    2476            0 :             write(*,2) 'xq_outer', k, xq_outer
    2477            0 :             write(*,2) 'xq_inner', k, xq_inner
    2478            0 :             write(*,2) 'new_cell_dq', k, new_cell_dq
    2479              :          end if
    2480              : 
    2481            0 :          dq_sum = 0d0
    2482            0 :          ke_sum = 0
    2483            0 :          if (xq_outer >= xout_old(nz_old)) then
    2484              :             ! new contained entirely in old center zone
    2485            0 :             k_outer = nz_old
    2486            0 :             if (k == k_dbg) &
    2487            0 :                write(*,2) 'new contained in old center', &
    2488            0 :                   k_outer, xout_old(k_outer)
    2489            0 :          else if (k == 1) then
    2490            0 :             k_outer = 1
    2491              :          else
    2492            0 :             k_outer = comes_from(k-1)
    2493              :          end if
    2494              : 
    2495            0 :          do kk = k_outer, nz_old  ! loop until reach xq_inner
    2496              : 
    2497            0 :             if (kk == nz_old) then
    2498            0 :                xq1 = 1d0
    2499              :             else
    2500            0 :                xq1 = xout_old(kk+1)
    2501              :             end if
    2502            0 :             if (xq1 <= xq_outer) cycle
    2503              : 
    2504            0 :             if (xq1 < xq_outer) then
    2505            0 :                ierr = -1
    2506            0 :                return
    2507              :             end if
    2508              : 
    2509            0 :             xq0 = xout_old(kk)
    2510            0 :             if (xq0 >= xq_outer .and. xq1 <= xq_inner) then  ! entire old kk is in new k
    2511              : 
    2512            0 :                dq = old_dq(kk)
    2513            0 :                dq_sum = dq_sum + dq
    2514              : 
    2515            0 :                if (dq_sum > new_cell_dq) then
    2516              :                   ! dq too large -- numerical roundoff problems
    2517            0 :                   dq = dq - (new_cell_dq - dq_sum)
    2518            0 :                   dq_sum = new_cell_dq
    2519              :                end if
    2520              : 
    2521            0 :                ke_sum = ke_sum + old_ke(kk)*dq/old_dq(kk)
    2522              : 
    2523            0 :                if (k == k_dbg) &
    2524            0 :                   write(*,3) 'new k contains all of old kk', &
    2525            0 :                      k, kk, old_ke(kk)*dq, ke_sum
    2526              : 
    2527            0 :             else if (xq0 <= xq_outer .and. xq1 >= xq_inner) then  ! entire new k is in old kk
    2528              : 
    2529            0 :                dq = new_dq(k)
    2530            0 :                dq_sum = dq_sum + dq
    2531            0 :                ke_sum = ke_sum + old_ke(kk)*dq/old_dq(kk)
    2532              : 
    2533            0 :                if (k == k_dbg) &
    2534            0 :                   write(*,3) 'all new k is in old kk', &
    2535            0 :                      k, kk, old_ke(kk)*dq, ke_sum
    2536              : 
    2537              :             else  ! only use the part of old kk that is in new k
    2538              : 
    2539            0 :                if (k == k_dbg) then
    2540            0 :                   write(*,*) 'only use the part of old kk that is in new k', xq_inner <= xq1
    2541            0 :                   write(*,1) 'xq_outer', xq_outer
    2542            0 :                   write(*,1) 'xq_inner', xq_inner
    2543            0 :                   write(*,1) 'xq0', xq0
    2544            0 :                   write(*,1) 'xq1', xq1
    2545            0 :                   write(*,1) 'dq_sum', dq_sum
    2546            0 :                   write(*,1) 'new_cell_dq', new_cell_dq
    2547            0 :                   write(*,1) 'new_cell_dq - dq_sum', new_cell_dq - dq_sum
    2548              :                end if
    2549              : 
    2550            0 :                if (xq_inner <= xq1) then  ! this is the last part of new k
    2551              : 
    2552            0 :                   dq = new_cell_dq - dq_sum
    2553            0 :                   dq_sum = new_cell_dq
    2554              : 
    2555              :                else  ! we avoid this case if possible because of numerical roundoff
    2556              : 
    2557            0 :                   if (k == k_dbg) write(*,3) 'we avoid this case if possible', k, kk
    2558              : 
    2559            0 :                   dq = max(0d0, xq1 - xq_outer)
    2560            0 :                   if (dq_sum + dq > new_cell_dq) dq = new_cell_dq - dq_sum
    2561            0 :                   dq_sum = dq_sum + dq
    2562              : 
    2563              :                end if
    2564              : 
    2565            0 :                if (k == k_dbg) then
    2566            0 :                   write(*,3) 'new k use only part of old kk', k, kk
    2567            0 :                   write(*,2) 'dq_sum', k, dq_sum
    2568            0 :                   write(*,2) 'dq', k, dq
    2569            0 :                   write(*,2) 'old_ke(kk)', kk, old_ke(kk)
    2570            0 :                   write(*,2) 'old ke_sum', k, ke_sum
    2571            0 :                   write(*,2) 'new ke_sum', k, ke_sum + old_ke(kk)*dq
    2572              :                end if
    2573              : 
    2574            0 :                ke_sum = ke_sum + old_ke(kk)*dq/old_dq(kk)
    2575              : 
    2576            0 :                if (dq <= 0) then
    2577            0 :                   ierr = -1
    2578              :                   !return
    2579            0 :                   write(*,*) 'dq <= 0', dq
    2580            0 :                   call mesa_error(__FILE__,__LINE__,'debugging: adjust1_u')
    2581              :                end if
    2582              : 
    2583              :             end if
    2584              : 
    2585            0 :             if (dq_sum >= new_cell_dq) then
    2586              :                exit
    2587              :             end if
    2588              : 
    2589              :          end do
    2590              : 
    2591            0 :          xh(i_u,k) = sqrt(ke_sum/new_cell_dq)  ! we have skipped the 1/2 xmstar factor
    2592            0 :          if (xh_old(i_u,comes_from(k)) < 0d0) xh(i_u,k) = -xh(i_u,k)
    2593              : 
    2594            0 :          if (k == k_dbg) then
    2595            0 : !$OMP critical (adjust1_u_dbg)
    2596            0 :             write(*,2) 'xh(i_u,k) new_dq', k, xh(i_u,k), new_dq(k)
    2597            0 :             write(*,2) 'xh_old(i_u,comes_from(k)) old_dq', &
    2598            0 :                comes_from(k), xh_old(i_u,comes_from(k)), old_dq(comes_from(k))
    2599            0 :             if (k == k_dbg) call mesa_error(__FILE__,__LINE__,'adjust1_u')
    2600              : !$OMP end critical (adjust1_u_dbg)
    2601              :             !stop
    2602              :          end if
    2603              : 
    2604            0 :       end subroutine adjust1_u
    2605              : 
    2606              : 
    2607            0 :       subroutine do_Hp_face( &
    2608              :             s, nz, nz_old, nzlo, nzhi, comes_from, xh, xh_old, &
    2609            0 :             xq, xq_old_plus1, xq_new, work, Hp_face_old_plus1, Hp_face_new, ierr)
    2610              :          use interp_1d_def
    2611              :          use interp_1d_lib
    2612              :          type (star_info), pointer :: s
    2613              :          integer, intent(in) :: nz, nz_old, nzlo, nzhi, comes_from(:)
    2614              :          real(dp), dimension(:,:), pointer :: xh, xh_old
    2615              :          real(dp), dimension(:), pointer :: work
    2616              :          real(dp), dimension(:) :: &
    2617              :             xq, xq_old_plus1, Hp_face_old_plus1, Hp_face_new, xq_new
    2618              :          integer, intent(out) :: ierr
    2619              : 
    2620              :          integer :: n, i_Hp, k
    2621              : 
    2622              :          include 'formats'
    2623              : 
    2624            0 :          ierr = 0
    2625            0 :          i_Hp = s% i_Hp
    2626            0 :          if (i_Hp == 0) return
    2627            0 :          n = nzhi - nzlo + 1
    2628              : 
    2629            0 :          do k=1,nz_old
    2630            0 :             Hp_face_old_plus1(k) = xh_old(i_Hp,k)
    2631              :          end do
    2632            0 :          Hp_face_old_plus1(nz_old+1) = Hp_face_old_plus1(nz_old)
    2633              : 
    2634              :          call interpolate_vector( &
    2635              :                nz_old+1, xq_old_plus1, n, xq_new, &
    2636              :                Hp_face_old_plus1, Hp_face_new, interp_pm, nwork, work, &
    2637            0 :                'mesh_adjust do_Hp_face', ierr)
    2638            0 :          if (ierr /= 0) then
    2639              :             return
    2640              :             write(*,*) 'interpolate_vector failed in do_Hp_face for remesh'
    2641              :             call mesa_error(__FILE__,__LINE__,'debug: mesh adjust: do_Hp_face')
    2642              :          end if
    2643              : 
    2644            0 :          do k=nzlo,nzhi
    2645            0 :             xh(i_Hp,k) = Hp_face_new(k+1-nzlo)
    2646              :          end do
    2647              : 
    2648            0 :          n = nzlo - 1
    2649            0 :          if (n > 0) then
    2650            0 :             do k=1,n
    2651            0 :                xh(i_Hp,k) = xh_old(i_Hp,k)
    2652              :             end do
    2653              :          end if
    2654              : 
    2655            0 :          if (nzhi < nz) then
    2656            0 :             n = nz - nzhi - 1  ! nz-n = nzhi+1
    2657            0 :             do k=0,n
    2658            0 :                xh(i_Hp,nz-k) = xh_old(i_Hp,nz_old-k)
    2659              :             end do
    2660              :          end if
    2661              : 
    2662            0 :       end subroutine do_Hp_face
    2663              : 
    2664              : 
    2665            0 :       subroutine do_etrb( &  ! same logic as do_u
    2666            0 :             s, nz, nz_old, cell_type, comes_from, &
    2667            0 :             old_xq, new_xq, old_dq, new_dq, xh, xh_old, &
    2668            0 :             xout_old, xout_new, old_eturb, ierr)
    2669            0 :          use alloc
    2670              :          type (star_info), pointer :: s
    2671              :          integer, intent(in) :: nz, nz_old
    2672              :          integer, dimension(:) :: cell_type, comes_from
    2673              :          real(dp), dimension(:) :: &
    2674              :             xout_old, xout_new, old_xq, new_xq, old_dq, new_dq, old_eturb
    2675              :          real(dp), dimension(:,:) :: xh, xh_old
    2676              :          integer, intent(out) :: ierr
    2677              : 
    2678              :          integer :: k, op_err, i_w
    2679            0 :          real(dp) :: old_eturb_tot, new_eturb_tot, xmstar, err
    2680              : 
    2681              :          include 'formats'
    2682            0 :          ierr = 0
    2683            0 :          i_w = s% i_w
    2684            0 :          xmstar = s% xmstar
    2685              : 
    2686            0 :          old_eturb_tot = 0d0
    2687            0 :          do k=1,nz_old
    2688            0 :             old_eturb(k) = old_dq(k)*pow2(xh_old(i_w,k))
    2689            0 :             old_eturb_tot = old_eturb_tot + old_eturb(k)
    2690              :          end do
    2691              : 
    2692            0 : !$OMP PARALLEL DO PRIVATE(k,op_err) SCHEDULE(dynamic,2)
    2693              :          do k = 1, nz
    2694              :             op_err = 0
    2695              :             call adjust1_etrb( &
    2696              :                s, k, nz, nz_old, cell_type, comes_from, xout_old, xout_new, &
    2697              :                old_dq, new_dq, old_eturb, i_w, xh, xh_old, op_err)
    2698              :             if (op_err /= 0) ierr = op_err
    2699              :          end do
    2700              : !$OMP END PARALLEL DO
    2701            0 :          if (ierr /= 0) then
    2702              :             return
    2703              :          end if
    2704              : 
    2705            0 :          new_eturb_tot = 0
    2706            0 :          do k=1,nz
    2707            0 :             new_eturb_tot = new_eturb_tot + new_dq(k)*pow2(xh(i_w,k))
    2708              :          end do
    2709              : 
    2710            0 :          err = abs(old_eturb_tot - new_eturb_tot)/max(new_eturb_tot,old_eturb_tot,1d0)
    2711            0 :          s% mesh_adjust_Eturb_conservation = err
    2712              : 
    2713            0 :          if (s% trace_mesh_adjust_error_in_conservation) then
    2714            0 :             write(*,2) 'mesh adjust error in conservation of turbulent energy', s% model_number, &
    2715            0 :                err, new_eturb_tot, old_eturb_tot
    2716            0 :             if (err > 1d-10) then
    2717            0 :                write(*,*) 'err too large'
    2718            0 :                call mesa_error(__FILE__,__LINE__,'do_etrb')
    2719              :             end if
    2720              :          end if
    2721              : 
    2722            0 :       end subroutine do_etrb
    2723              : 
    2724              : 
    2725            0 :       subroutine adjust1_etrb( &
    2726            0 :             s, k, nz, nz_old, cell_type, comes_from, xout_old, xout_new, &
    2727            0 :             old_dq, new_dq, old_eturb, i_w, xh, xh_old, ierr)
    2728              :          ! set new value for s% w(k) to conserve turbulent energy
    2729              :          type (star_info), pointer :: s
    2730              :          integer, intent(in) :: k, nz, nz_old, i_w
    2731              :          integer, dimension(:) :: cell_type, comes_from
    2732              :          real(dp), dimension(:), intent(in) :: &
    2733              :             xout_old, xout_new, old_dq, new_dq, old_eturb
    2734              :          real(dp), dimension(:,:) :: xh, xh_old
    2735              :          integer, intent(out) :: ierr
    2736              : 
    2737            0 :          real(dp) :: xq_outer, xq_inner, eturb_sum, &
    2738            0 :             xq0, xq1, new_cell_dq, dq_sum, dq
    2739              :          integer :: kk, k_outer
    2740              : 
    2741              :          integer, parameter :: k_dbg = -1
    2742              : 
    2743              :          include 'formats'
    2744              : 
    2745            0 :          ierr = 0
    2746              : 
    2747            0 :          if (cell_type(k) == unchanged_type .or. &
    2748              :                cell_type(k) == revised_type) then
    2749              :             ! just copy the old value
    2750            0 :             if (k == 1) then
    2751            0 :                xh(i_w,k) = xh_old(i_w,comes_from(k))
    2752            0 :                return
    2753              :             end if
    2754            0 :             if (cell_type(k-1) == unchanged_type) then
    2755            0 :                xh(i_w,k) = xh_old(i_w,comes_from(k))
    2756            0 :                return
    2757              :             end if
    2758              :          end if
    2759              : 
    2760            0 :          xq_outer = xout_new(k)
    2761            0 :          new_cell_dq = new_dq(k)
    2762            0 :          if (k < nz) then
    2763            0 :             xq_inner = xq_outer + new_cell_dq
    2764              :          else
    2765            0 :             xq_inner = 1d0
    2766              :          end if
    2767              : 
    2768            0 :          if (k == k_dbg) then
    2769            0 :             write(*,2) 'xq_outer', k, xq_outer
    2770            0 :             write(*,2) 'xq_inner', k, xq_inner
    2771            0 :             write(*,2) 'new_cell_dq', k, new_cell_dq
    2772              :          end if
    2773              : 
    2774            0 :          dq_sum = 0d0
    2775            0 :          eturb_sum = 0
    2776            0 :          if (xq_outer >= xout_old(nz_old)) then
    2777              :             ! new contained entirely in old center zone
    2778            0 :             k_outer = nz_old
    2779            0 :             if (k == k_dbg) &
    2780            0 :                write(*,2) 'new contained in old center', &
    2781            0 :                   k_outer, xout_old(k_outer)
    2782            0 :          else if (k == 1) then
    2783            0 :             k_outer = 1
    2784              :          else
    2785            0 :             k_outer = comes_from(k-1)
    2786              :          end if
    2787              : 
    2788            0 :          do kk = k_outer, nz_old  ! loop until reach xq_inner
    2789              : 
    2790            0 :             if (kk == nz_old) then
    2791            0 :                xq1 = 1d0
    2792              :             else
    2793            0 :                xq1 = xout_old(kk+1)
    2794              :             end if
    2795            0 :             if (xq1 <= xq_outer) cycle
    2796              : 
    2797            0 :             if (xq1 < xq_outer) then
    2798            0 :                ierr = -1
    2799            0 :                return
    2800              :             end if
    2801              : 
    2802            0 :             xq0 = xout_old(kk)
    2803            0 :             if (xq0 >= xq_outer .and. xq1 <= xq_inner) then  ! entire old kk is in new k
    2804              : 
    2805            0 :                dq = old_dq(kk)
    2806            0 :                dq_sum = dq_sum + dq
    2807              : 
    2808            0 :                if (dq_sum > new_cell_dq) then
    2809              :                   ! dq too large -- numerical roundoff problems
    2810            0 :                   dq = dq - (new_cell_dq - dq_sum)
    2811            0 :                   dq_sum = new_cell_dq
    2812              :                end if
    2813              : 
    2814            0 :                eturb_sum = eturb_sum + old_eturb(kk)*dq/old_dq(kk)
    2815              : 
    2816            0 :                if (k == k_dbg) &
    2817            0 :                   write(*,3) 'new k contains all of old kk', &
    2818            0 :                      k, kk, old_eturb(kk)*dq, eturb_sum
    2819              : 
    2820            0 :             else if (xq0 <= xq_outer .and. xq1 >= xq_inner) then  ! entire new k is in old kk
    2821              : 
    2822            0 :                dq = new_dq(k)
    2823            0 :                dq_sum = dq_sum + dq
    2824            0 :                eturb_sum = eturb_sum + old_eturb(kk)*dq/old_dq(kk)
    2825              : 
    2826            0 :                if (k == k_dbg) &
    2827            0 :                   write(*,3) 'all new k is in old kk', &
    2828            0 :                      k, kk, old_eturb(kk)*dq, eturb_sum
    2829              : 
    2830              :             else  ! only use the part of old kk that is in new k
    2831              : 
    2832            0 :                if (k == k_dbg) then
    2833            0 :                   write(*,*) 'only use the part of old kk that is in new k', xq_inner <= xq1
    2834            0 :                   write(*,1) 'xq_outer', xq_outer
    2835            0 :                   write(*,1) 'xq_inner', xq_inner
    2836            0 :                   write(*,1) 'xq0', xq0
    2837            0 :                   write(*,1) 'xq1', xq1
    2838            0 :                   write(*,1) 'dq_sum', dq_sum
    2839            0 :                   write(*,1) 'new_cell_dq', new_cell_dq
    2840            0 :                   write(*,1) 'new_cell_dq - dq_sum', new_cell_dq - dq_sum
    2841              :                end if
    2842              : 
    2843            0 :                if (xq_inner <= xq1) then  ! this is the last part of new k
    2844              : 
    2845            0 :                   dq = new_cell_dq - dq_sum
    2846            0 :                   dq_sum = new_cell_dq
    2847              : 
    2848              :                else  ! we avoid this case if possible because of numerical roundoff
    2849              : 
    2850            0 :                   if (k == k_dbg) write(*,3) 'we avoid this case if possible', k, kk
    2851              : 
    2852            0 :                   dq = max(0d0, xq1 - xq_outer)
    2853            0 :                   if (dq_sum + dq > new_cell_dq) dq = new_cell_dq - dq_sum
    2854            0 :                   dq_sum = dq_sum + dq
    2855              : 
    2856              :                end if
    2857              : 
    2858            0 :                if (k == k_dbg) then
    2859            0 :                   write(*,3) 'new k use only part of old kk', k, kk
    2860            0 :                   write(*,2) 'dq_sum', k, dq_sum
    2861            0 :                   write(*,2) 'dq', k, dq
    2862            0 :                   write(*,2) 'old_eturb(kk)', kk, old_eturb(kk)
    2863            0 :                   write(*,2) 'old eturb_sum', k, eturb_sum
    2864            0 :                   write(*,2) 'new eturb_sum', k, eturb_sum + old_eturb(kk)*dq
    2865              :                end if
    2866              : 
    2867            0 :                eturb_sum = eturb_sum + old_eturb(kk)*dq/old_dq(kk)
    2868              : 
    2869            0 :                if (dq <= 0) then
    2870            0 :                   ierr = -1
    2871              :                   !return
    2872            0 :                   write(*,*) 'dq <= 0', dq
    2873            0 :                   call mesa_error(__FILE__,__LINE__,'debugging: adjust1_etrb')
    2874              :                end if
    2875              : 
    2876              :             end if
    2877              : 
    2878            0 :             if (dq_sum >= new_cell_dq) then
    2879              :                exit
    2880              :             end if
    2881              : 
    2882              :          end do
    2883              : 
    2884            0 :          xh(i_w,k) = sqrt(max(0d0,eturb_sum/new_cell_dq))
    2885              : 
    2886            0 :       end subroutine adjust1_etrb
    2887              : 
    2888              :       end module mesh_adjust
        

Generated by: LCOV version 2.0-1