LCOV - code coverage report
Current view: top level - star/private - relax.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 2118 0
Test Date: 2026-05-14 09:58:24 Functions: 0.0 % 122 0

            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 relax
      21              : 
      22              :       use star_private_def
      23              :       use const_def, only: dp, msun, rsun, secyer, one_third, four_thirds_pi
      24              :       use utils_lib
      25              : 
      26              :       implicit none
      27              : 
      28              :       private
      29              :       public :: do_relax_z
      30              :       public :: do_relax_mass
      31              :       public :: do_relax_to_limit
      32              :       public :: do_relax_mass_scale
      33              :       public :: do_relax_num_steps
      34              :       public :: do_relax_to_radiative_core
      35              :       public :: do_relax_composition
      36              :       public :: do_relax_angular_momentum
      37              :       public :: do_relax_entropy
      38              :       public :: do_relax_core
      39              :       public :: do_relax_m_center
      40              :       public :: do_relax_r_center
      41              :       public :: do_relax_v_center
      42              :       public :: do_relax_l_center
      43              :       public :: do_relax_dxdt_nuc_factor
      44              :       public :: do_relax_eps_nuc_factor
      45              :       public :: do_relax_opacity_max
      46              :       public :: do_relax_max_surf_dq
      47              :       public :: do_relax_to_xaccrete
      48              :       public :: do_relax_y
      49              :       public :: do_relax_tau_factor
      50              :       public :: do_relax_opacity_factor
      51              :       public :: do_relax_uniform_omega
      52              :       public :: do_relax_irradiation
      53              :       public :: do_relax_mass_change
      54              :       public :: do_internal_evolve
      55              : 
      56              :       real(dp), parameter :: min_dlnz = -12
      57              :       real(dp), parameter :: min_z = 1d-12
      58              : 
      59              :       ! some relax routines depend on things such as other_energy and other_torque
      60              :       ! to which interpolation parameters cannot be passed directly. So for simplicity
      61              :       ! use these two global variables instead.
      62              :       integer :: relax_num_pts
      63              :       real(dp), pointer :: relax_work_array(:)
      64              : 
      65              :       contains
      66              : 
      67            0 :       subroutine do_relax_to_limit(id, restore_at_end, ierr)
      68              :          integer, intent(in) :: id
      69              :          logical, intent(in) :: restore_at_end
      70              :          integer, intent(out) :: ierr
      71              : 
      72              :          integer, parameter ::  lipar=1, lrpar=1
      73              : 
      74              :          type (star_info), pointer :: s
      75              : 
      76              :          integer, target :: ipar_ary(lipar)
      77              :          integer, pointer :: ipar(:)
      78              :          real(dp), target :: rpar_ary(lrpar)
      79              :          real(dp), pointer :: rpar(:)
      80            0 :          rpar => rpar_ary
      81            0 :          ipar => ipar_ary
      82              : 
      83              :          ierr = 0
      84            0 :          call get_star_ptr(id, s, ierr)
      85            0 :          if (ierr /= 0) return
      86              :          call do_internal_evolve( &
      87              :             id, before_relax_to_limit, relax_to_limit_adjust_model, &
      88              :             relax_to_limit_check_model, null_finish_model, &
      89            0 :             restore_at_end, lipar, ipar, lrpar, rpar, ierr)
      90              :       end subroutine do_relax_to_limit
      91              : 
      92              : 
      93            0 :       subroutine before_relax_to_limit(s, id, lipar, ipar, lrpar, rpar, ierr)
      94              :          type (star_info), pointer :: s
      95              :          integer, intent(in) :: id, lipar, lrpar
      96              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
      97              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
      98              :          integer, intent(out) :: ierr
      99            0 :          ierr = 0
     100            0 :       end subroutine before_relax_to_limit
     101              : 
     102            0 :       integer function relax_to_limit_adjust_model(s, id, lipar, ipar, lrpar, rpar)
     103              :          type (star_info), pointer :: s
     104              :          integer, intent(in) :: id, lipar, lrpar
     105              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     106              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     107            0 :          relax_to_limit_adjust_model = keep_going
     108            0 :       end function relax_to_limit_adjust_model
     109              : 
     110            0 :       integer function relax_to_limit_check_model(s, id, lipar, ipar, lrpar, rpar)
     111              :          use do_one_utils, only: do_bare_bones_check_model, do_check_limits
     112              :          type (star_info), pointer :: s
     113              :          integer, intent(in) :: id, lipar, lrpar
     114              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     115              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     116            0 :          relax_to_limit_check_model = do_bare_bones_check_model(id)
     117            0 :          if (relax_to_limit_check_model == keep_going) then
     118            0 :             relax_to_limit_check_model = do_check_limits(id)
     119            0 :             if (relax_to_limit_check_model == terminate) &
     120            0 :                s% termination_code = t_relax_finished_okay
     121              :          end if
     122            0 :       end function relax_to_limit_check_model
     123              : 
     124              : 
     125            0 :       subroutine do_relax_mass(id, new_mass, lg_max_abs_mdot, ierr)
     126              :          integer, intent(in) :: id
     127              :          real(dp), intent(in) :: new_mass, lg_max_abs_mdot
     128              :          integer, intent(out) :: ierr
     129              :          integer, parameter ::  lipar=1, lrpar=3
     130              :          integer :: max_model_number
     131              :          character (len=32) :: cool_wind_AGB_scheme, cool_wind_RGB_scheme
     132              :          real(dp) :: starting_dt_next, varcontrol_target, eps_mdot_factor
     133              :          logical :: adding_mass
     134              :          type (star_info), pointer :: s
     135              :          integer, target :: ipar_ary(lipar)
     136              :          integer, pointer :: ipar(:)
     137              :          real(dp), target :: rpar_ary(lrpar)
     138              :          real(dp), pointer :: rpar(:)
     139            0 :          rpar => rpar_ary
     140            0 :          ipar => ipar_ary
     141              :          include 'formats'
     142              :          ierr = 0
     143            0 :          call get_star_ptr(id, s, ierr)
     144            0 :          if (ierr /= 0) return
     145            0 :          if (abs(new_mass - s% star_mass) < 1d-12*new_mass) then
     146            0 :             s% star_mass = new_mass
     147            0 :             s% mstar = new_mass*Msun
     148            0 :             s% xmstar = s% mstar - s% M_center
     149            0 :             return
     150              :          end if
     151            0 :          write(*,'(A)')
     152            0 :          write(*,1) 'current mass', s% mstar/Msun
     153            0 :          write(*,1) 'relax to new_mass', new_mass
     154            0 :          write(*,1) 'lg_max_abs_mdot', lg_max_abs_mdot
     155            0 :          write(*,'(A)')
     156            0 :          if (new_mass <= 0) then
     157            0 :             ierr = -1
     158            0 :             write(*,*) 'invalid new mass'
     159            0 :             return
     160              :          end if
     161              : 
     162            0 :          rpar(1) = new_mass*Msun
     163            0 :          rpar(2) = lg_max_abs_mdot
     164            0 :          rpar(3) = s% mstar
     165              : 
     166            0 :          adding_mass = (new_mass > s% star_mass)
     167              : 
     168            0 :          cool_wind_AGB_scheme = s% cool_wind_AGB_scheme
     169            0 :          s% cool_wind_AGB_scheme = ''
     170              : 
     171            0 :          cool_wind_RGB_scheme = s% cool_wind_RGB_scheme
     172            0 :          s% cool_wind_RGB_scheme = ''
     173              : 
     174            0 :          varcontrol_target = s% varcontrol_target
     175            0 :          s% varcontrol_target = 1d-3
     176              : 
     177            0 :          eps_mdot_factor = s% eps_mdot_factor
     178            0 :          s% eps_mdot_factor = 0
     179              : 
     180            0 :          max_model_number = s% max_model_number
     181            0 :          s% max_model_number = -1111
     182            0 :          starting_dt_next = s% dt_next
     183              :          call do_internal_evolve( &
     184              :             id, before_evolve_relax_mass, relax_mass_adjust_model, relax_mass_check_model, &
     185            0 :             null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
     186            0 :          s% max_model_number = max_model_number
     187            0 :          s% dt_next = min(s% dt_next, starting_dt_next) * 1d-1
     188            0 :          s% initial_mass = new_mass
     189              : 
     190            0 :          s% cool_wind_AGB_scheme = cool_wind_AGB_scheme
     191            0 :          s% cool_wind_RGB_scheme = cool_wind_RGB_scheme
     192            0 :          s% varcontrol_target = varcontrol_target
     193            0 :          s% eps_mdot_factor = eps_mdot_factor
     194            0 :          s% star_mass = new_mass
     195            0 :          s% mstar = new_mass*Msun
     196            0 :          s% xmstar = s% mstar - s% M_center
     197              : 
     198            0 :          call error_check('relax mass',ierr)
     199              : 
     200            0 :          write(*,2) 's% max_model_number', s% max_model_number
     201              : 
     202              : 
     203              :       end subroutine do_relax_mass
     204              : 
     205              : 
     206            0 :       subroutine before_evolve_relax_mass(s, id, lipar, ipar, lrpar, rpar, ierr)
     207              :          type (star_info), pointer :: s
     208              :          integer, intent(in) :: id, lipar, lrpar
     209              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     210              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     211              :          integer, intent(out) :: ierr
     212            0 :          ierr = 0
     213            0 :          call setup_before_relax(s)
     214            0 :          s% mass_change = 0
     215            0 :          s% dt_next = min(s% dt_next, 1d4*secyer)
     216            0 :       end subroutine before_evolve_relax_mass
     217              : 
     218            0 :       integer function relax_mass_adjust_model(s, id, lipar, ipar, lrpar, rpar)
     219              :          type (star_info), pointer :: s
     220              :          integer, intent(in) :: id, lipar, lrpar
     221              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     222              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     223            0 :          relax_mass_adjust_model = keep_going
     224            0 :       end function relax_mass_adjust_model
     225              : 
     226            0 :       integer function relax_mass_check_model(s, id, lipar, ipar, lrpar, rpar)
     227              :          use do_one_utils, only:do_bare_bones_check_model
     228              :          type (star_info), pointer :: s
     229              :          integer, intent(in) :: id, lipar, lrpar
     230              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     231              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     232              :          integer :: ramp
     233              :          real(dp) :: &
     234              :             new_mass, old_mass, mdot, max_abs_mdot, abs_diff, lg_max_abs_mdot
     235              : 
     236              :          logical, parameter :: dbg = .false.
     237              : 
     238              :          include 'formats'
     239              : 
     240              :          if (dbg) write(*,*) 'relax_mass_check_model'
     241              : 
     242            0 :          relax_mass_check_model = do_bare_bones_check_model(id)
     243            0 :          if (relax_mass_check_model /= keep_going) then
     244            0 :             write(*,*) 'forced termination'
     245            0 :             return
     246              :          end if
     247              : 
     248            0 :          new_mass = rpar(1)
     249            0 :          lg_max_abs_mdot = rpar(2)
     250            0 :          if (lg_max_abs_mdot <= -100) then  ! use default
     251            0 :             if (s% star_mass < 0.003d0) then
     252            0 :                lg_max_abs_mdot = -7d0
     253            0 :             else if (s% star_mass < 0.006d0) then
     254            0 :                lg_max_abs_mdot = -6.3d0
     255            0 :             else if (s% star_mass < 0.01d0) then
     256            0 :                lg_max_abs_mdot = -6d0
     257            0 :             else if (s% star_mass < 0.1d0) then
     258            0 :                lg_max_abs_mdot = -4d0
     259              :             else
     260            0 :                lg_max_abs_mdot = -3d0
     261              :             end if
     262              :          end if
     263            0 :          max_abs_mdot = exp10(lg_max_abs_mdot)*(Msun/secyer)
     264            0 :          old_mass = rpar(3)
     265              : 
     266            0 :          if (s% model_number >= s% max_model_number .and. s% max_model_number > 0) then
     267            0 :             write(*,3) 's% model_number >= s% max_model_number', &
     268            0 :                s% model_number, s% max_model_number
     269            0 :             relax_mass_check_model = terminate
     270            0 :             return
     271              :          end if
     272              : 
     273            0 :          abs_diff = abs(s% mstar - new_mass)
     274            0 :          mdot = (new_mass - s% mstar)/s% dt_next
     275            0 :          if (abs(mdot) > max_abs_mdot) then
     276            0 :             mdot = sign(max_abs_mdot, mdot)
     277              :          end if
     278              : 
     279            0 :          if (abs_diff < 1d-4*new_mass .or. abs(mdot) < 1d-50) then
     280            0 :             s% mass_change = 0
     281            0 :             s% star_mass = new_mass
     282            0 :             s% mstar = new_mass*Msun
     283            0 :             s% xmstar = s% mstar - s% M_center
     284              :             s% mass_change = 0
     285            0 :             write(*,1) 's% tau_base =', s% tau_base
     286            0 :             write(*,1) 's% tau_factor =', s% tau_factor
     287            0 :             write(*,1) 'atm_option = ' // trim(s% atm_option)
     288            0 :             relax_mass_check_model = terminate
     289            0 :             s% termination_code = t_relax_finished_okay
     290            0 :             return
     291              :          end if
     292              : 
     293            0 :          s% max_timestep = abs(new_mass - s% mstar)/mdot
     294              : 
     295              :          if (dbg) then
     296              :             write(*,1) 'new_mass/Msun', new_mass/Msun
     297              :             write(*,1) 'old_mass/Msun', old_mass/Msun
     298              :             write(*,1) 'abs_diff/Msun', abs_diff/Msun
     299              :          end if
     300              : 
     301            0 :          ramp = 12
     302            0 :          if (s% model_number < ramp) then
     303            0 :             mdot = mdot * pow(1.1d0,dble(s% model_number-ramp))
     304              :          end if
     305              : 
     306            0 :          if (abs(mdot)*s% dt > 0.05d0*s% mstar) mdot = sign(0.05d0*s% mstar/s% dt,mdot)
     307              : 
     308            0 :          s% mass_change = mdot/(Msun/secyer)
     309              : 
     310              :          if (dbg) write(*,1) 's% mass_change', s% mass_change
     311              : 
     312            0 :       end function relax_mass_check_model
     313              : 
     314              : 
     315            0 :       subroutine do_relax_composition(  &
     316            0 :             id, num_steps_to_use, num_pts, species, xa, xq, ierr)
     317              :          integer, intent(in) :: id
     318              :          integer, intent(in) :: num_steps_to_use  ! use this many steps to do conversion
     319              :          integer, intent(in) :: num_pts
     320              :             ! length of composition vector; need not equal nz for current model
     321              :          integer, intent(in) :: species
     322              :             ! per point; must = number of species for current model
     323              :          real(dp), intent(in) :: xa(species,num_pts)  ! desired composition profile
     324              :          real(dp), intent(in) :: xq(num_pts)
     325              :          integer, intent(out) :: ierr
     326              : 
     327              :          integer, parameter ::  lipar=3
     328              :          integer :: lrpar, max_model_number
     329            0 :          real(dp), pointer :: rpar(:)
     330              :          real(dp) :: starting_dt_next, mix_factor, dxdt_nuc_factor
     331              :          logical :: do_element_diffusion, include_composition_in_eps_grav
     332              :          type (star_info), pointer :: s
     333            0 :          real(dp), pointer :: x(:), f1(:), f(:,:,:)
     334              :          integer, target :: ipar_ary(lipar)
     335              :          integer, pointer :: ipar(:)
     336            0 :          ipar => ipar_ary
     337              : 
     338              :          include 'formats'
     339              : 
     340              :          ierr = 0
     341              : 
     342            0 :          call get_star_ptr(id, s, ierr)
     343            0 :          if (ierr /= 0) return
     344              : 
     345            0 :          if (species /= s% species) then
     346            0 :             ierr = -1
     347            0 :             return
     348              :          end if
     349              : 
     350            0 :          ipar(1) = num_pts
     351            0 :          ipar(2) = num_steps_to_use
     352            0 :          ipar(3) = s% model_number
     353            0 :          lrpar = (1 + 4*species)*num_pts
     354            0 :          allocate(rpar(lrpar), stat=ierr)
     355            0 :          if (ierr /= 0) return
     356              : 
     357            0 :          x(1:num_pts) => rpar(1:num_pts)
     358            0 :          f1(1:4*num_pts*species) => rpar(num_pts+1:lrpar)
     359            0 :          f(1:4,1:num_pts,1:species) => f1(1:4*num_pts*species)
     360              : 
     361            0 :          call store_rpar(species, num_pts, ierr)
     362            0 :          if (ierr /= 0) return
     363              : 
     364            0 :          max_model_number = s% max_model_number
     365            0 :          s% max_model_number = num_steps_to_use + s% model_number + 1
     366            0 :          write(*,*) 'relax_composition: num_steps_to_use', num_steps_to_use
     367              : 
     368            0 :          dxdt_nuc_factor = s% dxdt_nuc_factor
     369            0 :          s% dxdt_nuc_factor = 0  ! turn off composition change by nuclear burning
     370            0 :          mix_factor = s% mix_factor
     371            0 :          s% mix_factor = 0  ! turn off mixing
     372            0 :          do_element_diffusion = s% do_element_diffusion
     373            0 :          s% do_element_diffusion = .false.  ! turn off diffusion
     374            0 :          include_composition_in_eps_grav = s% include_composition_in_eps_grav
     375            0 :          s% include_composition_in_eps_grav = .false.  ! don't need energetic effects of artificial changes
     376            0 :          starting_dt_next = s% dt_next
     377              :          call do_internal_evolve( &
     378              :                id, before_evolve_relax_composition, &
     379              :                relax_composition_adjust_model, relax_composition_check_model, &
     380            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
     381              : 
     382            0 :          s% max_model_number = max_model_number
     383            0 :          s% dt_next = starting_dt_next
     384            0 :          s% dxdt_nuc_factor = dxdt_nuc_factor
     385            0 :          s% mix_factor = mix_factor
     386            0 :          s% do_element_diffusion = do_element_diffusion
     387            0 :          s% include_composition_in_eps_grav = include_composition_in_eps_grav
     388              : 
     389            0 :          call error_check('relax composition',ierr)
     390              : 
     391            0 :          deallocate(rpar)
     392              : 
     393              : 
     394              :          contains
     395              : 
     396              : 
     397            0 :          subroutine store_rpar(species, num_pts, ierr)  ! get interpolation info
     398              :             use interp_1d_def, only: pm_work_size
     399              :             use interp_1d_lib, only: interp_pm
     400              :             integer, intent(in) :: species, num_pts
     401              :             integer, intent(out) :: ierr
     402              :             integer :: j, op_err
     403            0 :             real(dp), pointer :: interp_work(:), work(:), p(:)
     404            0 :             allocate(interp_work(num_pts*pm_work_size*species), stat=ierr)
     405            0 :             if (ierr /= 0) return
     406            0 :             x(:) = xq(:)
     407            0 :             do j=1, species  ! make piecewise monotonic cubic interpolants
     408              :                op_err = 0
     409            0 :                f(1,1:num_pts,j) = xa(j,1:num_pts)
     410              :                work(1:num_pts*pm_work_size) => &
     411            0 :                   interp_work(1+num_pts*pm_work_size*(j-1):num_pts*pm_work_size*j)
     412            0 :                p(1:4*num_pts) => f1(1+4*num_pts*(j-1):4*num_pts*j)
     413              :                call interp_pm(x, num_pts, p, pm_work_size, work, &
     414            0 :                   'do_relax_composition', op_err)
     415            0 :                if (op_err /= 0) ierr = op_err
     416              :             end do
     417            0 :             deallocate(interp_work)
     418            0 :          end subroutine store_rpar
     419              : 
     420              :       end subroutine do_relax_composition
     421              : 
     422              : 
     423            0 :       subroutine before_evolve_relax_composition(s, id, lipar, ipar, lrpar, rpar, ierr)
     424              :          type (star_info), pointer :: s
     425              :          integer, intent(in) :: id, lipar, lrpar
     426              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     427              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     428              :          integer, intent(out) :: ierr
     429            0 :          ierr = 0
     430            0 :          call setup_before_relax(s)
     431            0 :       end subroutine before_evolve_relax_composition
     432              : 
     433            0 :       integer function relax_composition_adjust_model(s, id, lipar, ipar, lrpar, rpar)
     434              :          type (star_info), pointer :: s
     435              :          integer, intent(in) :: id, lipar, lrpar
     436              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     437              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     438              :          integer :: num_pts, num_steps_to_use, species, starting_model_number, ierr
     439              :          real(dp) :: lambda, avg_err
     440              : 
     441            0 :          real(dp), pointer :: x(:)  ! =(num_pts)
     442            0 :          real(dp), pointer :: f1(:)  ! =(4, num_pts, species)
     443              : 
     444              :          include 'formats'
     445              : 
     446            0 :          num_pts = ipar(1)
     447            0 :          num_steps_to_use = ipar(2)
     448            0 :          starting_model_number = ipar(3)
     449            0 :          species = s% species
     450              : 
     451            0 :          if (lrpar /= (1 + 4*species)*num_pts) then
     452            0 :             write(*,*) 'bad lrpar for relax_composition_check_model'
     453            0 :             relax_composition_adjust_model = terminate
     454            0 :             return
     455              :          end if
     456              : 
     457              :          ierr = 0
     458            0 :          if (s% job% timescale_for_relax_composition < 0d0) then
     459              :             lambda = min(1d0, max(0d0, (s% model_number - starting_model_number - 1) &
     460            0 :                  / max(1d0, dble(num_steps_to_use) - 1)))
     461              :          else
     462            0 :             lambda = min(1d0, s% dt/s% job% timescale_for_relax_composition)
     463              :          end if
     464              : 
     465            0 :          x(1:num_pts) => rpar(1:num_pts)
     466            0 :          f1(1:4*num_pts*species) => rpar(num_pts+1:lrpar)
     467            0 :          call adjust_xa(species, num_pts, avg_err, ierr)
     468            0 :          if (ierr /= 0) relax_composition_adjust_model = terminate
     469              : 
     470            0 :          write(*,1) 'avg remaining difference, lambda', avg_err, lambda
     471              : 
     472            0 :          relax_composition_adjust_model = keep_going
     473              : 
     474              :          contains
     475              : 
     476              : 
     477            0 :          subroutine adjust_xa(species, num_pts, avg_err, ierr)
     478              :             use interp_1d_lib, only: interp_values
     479              :             integer, intent(in) :: species, num_pts
     480              :             real(dp), intent(out) :: avg_err
     481              :             integer, intent(out) :: ierr
     482              :             integer :: j, k, nz, op_err
     483            0 :             real(dp), pointer :: vals(:,:), xq(:), f(:)
     484            0 :             ierr = 0
     485            0 :             nz = s% nz
     486            0 :             allocate(vals(species, nz), xq(nz), stat=ierr)
     487            0 :             if (ierr /= 0) return
     488            0 :             xq(1) = 0.5d0*s% dq(1)  ! xq for cell center
     489            0 :             do k = 2, nz
     490            0 :                xq(k) = xq(k-1) + 0.5d0*(s% dq(k) + s% dq(k-1))
     491              :             end do
     492            0 : !$OMP PARALLEL DO PRIVATE(j,op_err,f) SCHEDULE(dynamic,2)
     493              :             do j=1, species  ! interpolate target composition
     494              :                f(1:4*num_pts) => f1(1+(j-1)*4*num_pts:j*4*num_pts)
     495              :                call interp_values(x, num_pts, f, nz, xq, vals(j,:), op_err)
     496              :                ! enforce non-negative mass fractions
     497              :                ! if the abundance switches back and forth between 0 and 1d-99,
     498              :                ! then small negative abundances ~ -1d-115 can be generated
     499              :                do k = 1, nz
     500              :                   if (vals(j,k) < 0d0) vals(j,k) = 0d0
     501              :                end do
     502              :                if (op_err /= 0) ierr = op_err
     503              :                s% xa(j,1:nz) = (1d0-lambda)*s% xa(j,1:nz) + lambda*vals(j,1:nz)
     504              :             end do
     505              : !$OMP END PARALLEL DO
     506            0 :             avg_err = sum(abs(s% xa(1:species,1:nz)-vals(1:species,1:nz)))/(nz*species)
     507            0 :             deallocate(vals, xq)
     508            0 :          end subroutine adjust_xa
     509              : 
     510              :       end function relax_composition_adjust_model
     511              : 
     512            0 :       integer function relax_composition_check_model(s, id, lipar, ipar, lrpar, rpar)
     513              :          use do_one_utils, only:do_bare_bones_check_model
     514              :          type (star_info), pointer :: s
     515              :          integer, intent(in) :: id, lipar, lrpar
     516              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     517              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     518              : 
     519              :          integer :: num_steps_to_use, starting_model_number
     520              : 
     521              :          include 'formats'
     522              : 
     523            0 :          relax_composition_check_model = do_bare_bones_check_model(id)
     524            0 :          if (relax_composition_check_model /= keep_going) return
     525              : 
     526            0 :          num_steps_to_use = ipar(2)
     527            0 :          starting_model_number = ipar(3)
     528              : 
     529            0 :          if (s% job% timescale_for_relax_composition < 0d0) then
     530            0 :             if (s% model_number - starting_model_number >= num_steps_to_use) then
     531            0 :                relax_composition_check_model = terminate
     532            0 :                s% termination_code = t_relax_finished_okay
     533            0 :                return
     534              :             end if
     535              :          else
     536              :             if (s% generations > 1 .and. &
     537            0 :                s% dt > s% job% timescale_for_relax_composition .and. &
     538              :                s% dt_old > s% job% timescale_for_relax_composition) then
     539            0 :                relax_composition_check_model = terminate
     540            0 :                s% termination_code = t_relax_finished_okay
     541            0 :                return
     542              :             end if
     543              :          end if
     544              : 
     545              : 
     546              :       end function relax_composition_check_model
     547              : 
     548              : 
     549            0 :       subroutine do_relax_to_xaccrete(id, num_steps_to_use, ierr)
     550              :          use adjust_xyz, only: get_xa_for_accretion
     551              : 
     552              :          integer, intent(in) :: id
     553              :          integer, intent(in) :: num_steps_to_use  ! use this many steps to do conversion
     554              :          integer, intent(out) :: ierr
     555              : 
     556              :          integer, parameter :: lipar=2
     557              :          integer :: lrpar, max_model_number, species
     558            0 :          real(dp), pointer :: rpar(:)
     559              :          real(dp) :: starting_dt_next, mix_factor, dxdt_nuc_factor
     560              :          logical :: do_element_diffusion
     561              :          type (star_info), pointer :: s
     562            0 :          real(dp), pointer :: xa(:)
     563              :          integer, target :: ipar_ary(lipar)
     564              :          integer, pointer :: ipar(:)
     565            0 :          ipar => ipar_ary
     566              : 
     567              :          include 'formats'
     568              : 
     569              :          ierr = 0
     570              : 
     571            0 :          call get_star_ptr(id, s, ierr)
     572            0 :          if (ierr /= 0) return
     573              : 
     574            0 :          species = s% species
     575            0 :          ipar(1) = s% model_number
     576            0 :          ipar(2) = num_steps_to_use
     577            0 :          if (num_steps_to_use <= 0) then
     578            0 :             ierr = -1
     579            0 :             write(*,2) 'invalid num_steps_to_use to relax_to_xaccrete', num_steps_to_use
     580            0 :             return
     581              :          end if
     582              : 
     583            0 :          lrpar = species
     584            0 :          allocate(rpar(lrpar), stat=ierr)
     585            0 :          if (ierr /= 0) return
     586              : 
     587            0 :          xa(1:species) => rpar(1:species)
     588              : 
     589            0 :          call get_xa_for_accretion(s, xa, ierr)
     590            0 :          if (ierr /= 0) then
     591            0 :             if (s% report_ierr) &
     592            0 :                write(*, *) 'get_xa_for_accretion failed in relax_to_xaccrete'
     593            0 :             deallocate(rpar)
     594            0 :             return
     595              :          end if
     596              : 
     597            0 :          max_model_number = s% max_model_number
     598            0 :          s% max_model_number = num_steps_to_use + 1
     599            0 :          write(*,*) 'num_steps_to_use', num_steps_to_use
     600              : 
     601            0 :          dxdt_nuc_factor = s% dxdt_nuc_factor
     602            0 :          s% dxdt_nuc_factor = 0  ! turn off composition change by nuclear burning
     603            0 :          mix_factor = s% mix_factor
     604            0 :          s% mix_factor = 0  ! turn off mixing
     605              :          do_element_diffusion = s% do_element_diffusion
     606            0 :          do_element_diffusion = .false.  ! turn off diffusion
     607            0 :          starting_dt_next = s% dt_next
     608              : 
     609              :          call do_internal_evolve( &
     610              :                id, before_evolve_relax_to_xaccrete, &
     611              :                relax_to_xaccrete_adjust_model, relax_to_xaccrete_check_model, &
     612            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
     613              : 
     614            0 :          s% max_model_number = max_model_number
     615            0 :          s% dt_next = starting_dt_next
     616            0 :          s% dxdt_nuc_factor = dxdt_nuc_factor
     617            0 :          s% mix_factor = mix_factor
     618            0 :          s% do_element_diffusion = do_element_diffusion
     619              : 
     620            0 :          call error_check('relax to xacrrete',ierr)
     621              : 
     622            0 :          deallocate(rpar)
     623              : 
     624            0 :       end subroutine do_relax_to_xaccrete
     625              : 
     626              : 
     627            0 :       subroutine before_evolve_relax_to_xaccrete(s, id, lipar, ipar, lrpar, rpar, ierr)
     628              :          type (star_info), pointer :: s
     629              :          integer, intent(in) :: id, lipar, lrpar
     630              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     631              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     632              :          integer, intent(out) :: ierr
     633            0 :          ierr = 0
     634            0 :          call setup_before_relax(s)
     635            0 :       end subroutine before_evolve_relax_to_xaccrete
     636              : 
     637            0 :       integer function relax_to_xaccrete_adjust_model(s, id, lipar, ipar, lrpar, rpar)
     638              :          type (star_info), pointer :: s
     639              :          integer, intent(in) :: id, lipar, lrpar
     640              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     641              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     642            0 :          relax_to_xaccrete_adjust_model = keep_going
     643            0 :       end function relax_to_xaccrete_adjust_model
     644              : 
     645            0 :       integer function relax_to_xaccrete_check_model(s, id, lipar, ipar, lrpar, rpar)
     646              :          use do_one_utils, only:do_bare_bones_check_model
     647              :          type (star_info), pointer :: s
     648              :          integer, intent(in) :: id, lipar, lrpar
     649              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     650              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     651              : 
     652              :          integer :: num_steps_to_use, starting_model_number, species, k, j
     653            0 :          real(dp), pointer :: xa(:)
     654              :          real(dp) :: frac
     655              : 
     656              :          include 'formats'
     657              : 
     658            0 :          relax_to_xaccrete_check_model = do_bare_bones_check_model(id)
     659            0 :          if (relax_to_xaccrete_check_model /= keep_going) return
     660              : 
     661            0 :          starting_model_number = ipar(1)
     662            0 :          num_steps_to_use = ipar(2)
     663            0 :          species = s% species
     664              : 
     665            0 :          frac = dble(s% model_number - starting_model_number)/dble(num_steps_to_use)
     666            0 :          frac = frac*frac
     667              : 
     668            0 :          if (lrpar /= species) then
     669            0 :             write(*,*) 'bad lrpar for relax_to_xaccrete_check_model'
     670            0 :             relax_to_xaccrete_check_model = terminate
     671              :          end if
     672              : 
     673            0 :          xa(1:species) => rpar(1:species)
     674              : 
     675            0 :          do k=1,s% nz
     676            0 :             do j=1,species
     677            0 :                s% xa(j,k) = (1d0-frac)*s% xa(j,k) + frac*xa(j)
     678              :             end do
     679              :          end do
     680              : 
     681            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
     682            0 :             write(*,2) 'relax to xaccrete: fraction', s% model_number, frac
     683              : 
     684            0 :          if (s% model_number - starting_model_number >= num_steps_to_use) then
     685            0 :             relax_to_xaccrete_check_model = terminate
     686            0 :             s% termination_code = t_relax_finished_okay
     687            0 :             return
     688              :          end if
     689              : 
     690              : 
     691            0 :       end function relax_to_xaccrete_check_model
     692              : 
     693            0 :       subroutine do_relax_entropy(  &
     694            0 :             id, max_steps_to_use, num_pts, entropy, xq, ierr)
     695              :          use alloc, only: alloc_extras, dealloc_extras
     696              :          integer, intent(in) :: id
     697              :          integer, intent(in) :: max_steps_to_use  ! use this many steps to do conversion
     698              :          integer, intent(in) :: num_pts
     699              :             ! length of entropy vector; need not equal nz for current model
     700              :          real(dp), intent(in) :: entropy(num_pts)  ! desired entropy profile
     701              :          real(dp), intent(in) :: xq(num_pts)
     702              :          integer, intent(out) :: ierr
     703              : 
     704              :          integer, parameter ::  lipar=2
     705              :          integer :: lrpar, max_model_number
     706            0 :          real(dp), pointer :: rpar(:)
     707              :          real(dp) :: starting_dt_next, mix_factor, dxdt_nuc_factor, max_years_for_timestep, time
     708              :          logical :: do_element_diffusion, use_other_energy
     709              :          type (star_info), pointer :: s
     710            0 :          real(dp), pointer :: x(:), f1(:), f(:,:)
     711              :          integer, target :: ipar_ary(lipar)
     712              :          integer, pointer :: ipar(:)
     713              :          procedure (other_energy_interface), pointer :: &
     714              :             other_energy => null()
     715              : 
     716            0 :          ipar => ipar_ary
     717              : 
     718              :          include 'formats'
     719              : 
     720              :          ierr = 0
     721              : 
     722            0 :          call get_star_ptr(id, s, ierr)
     723            0 :          if (ierr /= 0) return
     724              : 
     725            0 :          max_model_number = s% max_model_number
     726            0 :          s% max_model_number = max_steps_to_use + s% model_number + 1
     727            0 :          write(*,*) 'relax_entropy: max_steps_to_use', max_steps_to_use
     728              : 
     729            0 :          ipar(1) = num_pts
     730            0 :          ipar(2) = s% max_model_number
     731            0 :          lrpar = 5*num_pts
     732            0 :          allocate(rpar(lrpar), stat=ierr)
     733            0 :          if (ierr /= 0) return
     734              : 
     735            0 :          x(1:num_pts) => rpar(1:num_pts)
     736            0 :          f1(1:4*num_pts) => rpar(num_pts+1:lrpar)
     737            0 :          f(1:4,1:num_pts) => f1(1:4*num_pts)
     738              : 
     739            0 :          call store_rpar(num_pts, ierr)
     740            0 :          if (ierr /= 0) return
     741              : 
     742              :          ! need to use global variables, as relax_entropy uses
     743              :          ! the other_energy routine to which it can't pass rpar
     744            0 :          relax_num_pts = num_pts
     745            0 :          relax_work_array => rpar
     746              : 
     747            0 :          dxdt_nuc_factor = s% dxdt_nuc_factor
     748            0 :          s% dxdt_nuc_factor = 0  ! turn off composition change by nuclear burning
     749            0 :          mix_factor = s% mix_factor
     750            0 :          s% mix_factor = 0  ! turn off mixing
     751            0 :          do_element_diffusion = s% do_element_diffusion
     752            0 :          s% do_element_diffusion = .false.  ! turn off diffusion
     753            0 :          starting_dt_next = s% dt_next
     754            0 :          max_years_for_timestep = s% max_years_for_timestep
     755            0 :          s% max_years_for_timestep = s% job% max_dt_for_relax_entropy
     756            0 :          s% dt_next = min(s% dt_next, s% job% max_dt_for_relax_entropy * secyer)
     757            0 :          use_other_energy = s% use_other_energy
     758            0 :          s% use_other_energy = .true.
     759            0 :          other_energy => s% other_energy
     760            0 :          s% other_energy => entropy_relax_other_energy
     761            0 :          time = s% time
     762            0 :          s% time = 0d0
     763              : 
     764              :          call do_internal_evolve( &
     765              :                id, before_evolve_relax_entropy, &
     766              :                relax_entropy_adjust_model, relax_entropy_check_model, &
     767            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
     768              : 
     769            0 :          s% max_model_number = max_model_number
     770            0 :          s% dt_next = starting_dt_next
     771            0 :          s% dxdt_nuc_factor = dxdt_nuc_factor
     772            0 :          s% mix_factor = mix_factor
     773            0 :          s% do_element_diffusion = do_element_diffusion
     774            0 :          s% max_years_for_timestep = max_years_for_timestep
     775            0 :          s% use_other_energy = use_other_energy
     776            0 :          s% other_energy => other_energy
     777            0 :          s% time = time
     778              : 
     779            0 :          call error_check('relax entropy',ierr)
     780              : 
     781            0 :          deallocate(rpar)
     782              : 
     783              : 
     784              :          contains
     785              : 
     786              : 
     787            0 :          subroutine store_rpar(num_pts, ierr)  ! get interpolation info
     788              :             use interp_1d_def, only: pm_work_size
     789              :             use interp_1d_lib, only: interp_pm
     790              :             integer, intent(in) :: num_pts
     791              :             integer, intent(out) :: ierr
     792              :             integer :: op_err
     793            0 :             real(dp), pointer :: interp_work(:), work(:), p(:)
     794            0 :             allocate(interp_work(num_pts*pm_work_size), stat=ierr)
     795            0 :             if (ierr /= 0) return
     796            0 :             x(:) = xq(:)
     797              :             op_err = 0
     798            0 :             f(1,1:num_pts) = entropy(1:num_pts)
     799              :             work(1:num_pts*pm_work_size) => &
     800            0 :                interp_work(1:num_pts*pm_work_size)
     801            0 :             p(1:4*num_pts) => f1(1:4*num_pts)
     802              :             call interp_pm(x, num_pts, p, pm_work_size, work, &
     803            0 :                'do_relax_entropy', op_err)
     804            0 :             if (op_err /= 0) ierr = op_err
     805            0 :             deallocate(interp_work)
     806            0 :          end subroutine store_rpar
     807              : 
     808              :       end subroutine do_relax_entropy
     809              : 
     810            0 :       subroutine before_evolve_relax_entropy(s, id, lipar, ipar, lrpar, rpar, ierr)
     811              :          type (star_info), pointer :: s
     812              :          integer, intent(in) :: id, lipar, lrpar
     813              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     814              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     815              :          integer, intent(out) :: ierr
     816            0 :          ierr = 0
     817            0 :          call setup_before_relax(s)
     818            0 :       end subroutine before_evolve_relax_entropy
     819              : 
     820            0 :       integer function relax_entropy_adjust_model(s, id, lipar, ipar, lrpar, rpar)
     821              :          type (star_info), pointer :: s
     822              :          integer, intent(in) :: id, lipar, lrpar
     823              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     824              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     825            0 :          relax_entropy_adjust_model = keep_going
     826            0 :       end function relax_entropy_adjust_model
     827              : 
     828            0 :       integer function relax_entropy_check_model(s, id, lipar, ipar, lrpar, rpar)
     829              :          use do_one_utils, only: do_bare_bones_check_model
     830              :          type (star_info), pointer :: s
     831              :          integer, intent(in) :: id, lipar, lrpar
     832              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     833              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     834              : 
     835              :          integer :: num_pts, ierr, max_model_number
     836              :          real(dp) :: avg_err
     837            0 :          real(dp), pointer :: x(:)  ! =(num_pts)
     838            0 :          real(dp), pointer :: f1(:)  ! =(4, num_pts)
     839              : 
     840              :          include 'formats'
     841              : 
     842            0 :          relax_entropy_check_model = do_bare_bones_check_model(id)
     843            0 :          if (relax_entropy_check_model /= keep_going) return
     844              : 
     845            0 :          if (lipar /= 2) then
     846            0 :             write(*,*) 'bad lipar for relax_entropy_check_model'
     847            0 :             relax_entropy_check_model = terminate
     848            0 :             return
     849              :          end if
     850              : 
     851            0 :          num_pts = ipar(1)
     852            0 :          max_model_number = ipar(2)
     853              : 
     854            0 :          if (lrpar /= 5*num_pts) then
     855            0 :             write(*,*) 'bad lrpar for relax_entropy_check_model'
     856            0 :             relax_entropy_check_model = terminate
     857              :          end if
     858              : 
     859              :          ierr = 0
     860            0 :          x(1:num_pts) => rpar(1:num_pts)
     861            0 :          f1(1:4*num_pts) => rpar(num_pts+1:lrpar)
     862            0 :          call adjust_entropy(num_pts, avg_err, ierr)
     863            0 :          if (ierr /= 0) relax_entropy_check_model = terminate
     864              : 
     865            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
     866            0 :             write(*,*) 'relax_entropy avg rel err, dt, model', avg_err, s% dt/secyer, s% model_number
     867              : 
     868              : 
     869            0 :          if (s% star_age >= s% job% timescale_for_relax_entropy*s% job% num_timescales_for_relax_entropy) then
     870            0 :             relax_entropy_check_model = terminate
     871            0 :             s% termination_code = t_relax_finished_okay
     872            0 :             return
     873              :          end if
     874              : 
     875            0 :          if (s% model_number >= max_model_number) then
     876            0 :             write(*,*) "Terminated relax because of max_model_number instead of relax_time"
     877            0 :             relax_entropy_check_model = terminate
     878            0 :             s% termination_code = t_relax_finished_okay
     879            0 :             return
     880              :          end if
     881              : 
     882              : 
     883              :          contains
     884              : 
     885              : 
     886            0 :          subroutine adjust_entropy(num_pts, avg_err, ierr)
     887              :             use interp_1d_lib, only: interp_values
     888              :             integer, intent(in) :: num_pts
     889              :             real(dp), intent(out) :: avg_err
     890              :             integer, intent(out) :: ierr
     891              :             integer :: k, nz, op_err
     892              :             real(dp) :: dentropy_sum
     893            0 :             real(dp), pointer :: vals(:), xq(:), f(:), entropy(:)
     894              :             ierr = 0
     895            0 :             nz = s% nz
     896            0 :             allocate(vals(nz), xq(nz), stat=ierr)
     897            0 :             if (ierr /= 0) return
     898            0 :             xq(1) = s% dq(1)/2  ! xq for cell center
     899            0 :             do k = 2, nz
     900            0 :                xq(k) = xq(k-1) + (s% dq(k) + s% dq(k-1))/2
     901              :             end do
     902            0 :             dentropy_sum = 0
     903            0 :             f(1:4*num_pts) => f1(1:4*num_pts)
     904            0 :             call interp_values(x, num_pts, f, nz, xq, vals(:), op_err)
     905            0 :             if (op_err /= 0) ierr = op_err
     906            0 :             allocate(entropy(1:nz))
     907            0 :             do k=1,nz
     908            0 :                entropy(k) = exp(s% lnS(k))
     909              :             end do
     910              : 
     911            0 :             dentropy_sum = sum(abs((entropy(1:nz)-vals(1:nz))/vals(1:nz)))
     912            0 :             avg_err = dentropy_sum/nz
     913            0 :             deallocate(vals, xq, entropy)
     914            0 :          end subroutine adjust_entropy
     915              : 
     916              :       end function relax_entropy_check_model
     917              : 
     918            0 :       subroutine entropy_relax_other_energy(id, ierr)
     919              :          use interp_1d_lib, only: interp_values
     920              :          use auto_diff_support
     921              :          integer, intent(in) :: id
     922              :          integer, intent(out) :: ierr
     923              :          type (star_info), pointer :: s
     924              :          integer :: k, nz, num_pts
     925            0 :          real(dp), pointer :: vals(:), xq(:), x(:), f(:)
     926              :          ierr = 0
     927            0 :          call star_ptr(id, s, ierr)
     928              : 
     929            0 :          nz = s% nz
     930            0 :          num_pts = relax_num_pts
     931            0 :          allocate(vals(nz), xq(nz), stat=ierr)
     932            0 :          f(1:4*num_pts) => relax_work_array(num_pts+1:5*num_pts)
     933            0 :          x(1:num_pts) => relax_work_array(1:num_pts)
     934            0 :          xq(1) = s% dq(1)/2  ! xq for cell center
     935            0 :          do k = 2, nz
     936            0 :             xq(k) = xq(k-1) + (s% dq(k) + s% dq(k-1))/2
     937              :          end do
     938            0 :          call interp_values(x, num_pts, f, nz, xq, vals(:), ierr)
     939            0 :          if (ierr /= 0) return
     940            0 :          do k = 1, s% nz
     941            0 :             s% extra_heat(k) = ( 1d0 - exp(s%lnS(k))/vals(k) ) * exp(s%lnE(k))
     942            0 :             s% extra_heat(k) = s% extra_heat(k) / (s% job% timescale_for_relax_entropy * secyer)
     943              :          end do
     944            0 :       end subroutine entropy_relax_other_energy
     945              : 
     946            0 :       subroutine do_relax_angular_momentum(  &
     947            0 :             id, max_steps_to_use, num_pts, angular_momentum, xq, ierr)
     948              :          use alloc, only: alloc_extras, dealloc_extras
     949              :          integer, intent(in) :: id
     950              :          integer, intent(in) :: max_steps_to_use  ! use this many steps to do conversion
     951              :          integer, intent(in) :: num_pts
     952              :             ! length of angular momentum vector; need not equal nz for current model
     953              :          real(dp), intent(in) :: angular_momentum(num_pts)  ! desired angular momentum profile
     954              :          real(dp), intent(in) :: xq(num_pts)
     955              :          integer, intent(out) :: ierr
     956              : 
     957              :          integer, parameter ::  lipar=2
     958              :          integer :: lrpar, max_model_number
     959            0 :          real(dp), pointer :: rpar(:)
     960              :          real(dp) :: starting_dt_next, mix_factor, dxdt_nuc_factor, max_timestep, &
     961              :             am_D_mix_factor, time
     962              :          logical :: do_element_diffusion, use_other_torque
     963              :          type (star_info), pointer :: s
     964            0 :          real(dp), pointer :: x(:), f1(:), f(:,:)
     965              :          integer, target :: ipar_ary(lipar)
     966              :          integer, pointer :: ipar(:)
     967              :          procedure (other_torque_interface), pointer :: &
     968              :             other_torque => null()
     969              : 
     970            0 :          ipar => ipar_ary
     971              : 
     972              :          include 'formats'
     973              : 
     974              :          ierr = 0
     975              : 
     976            0 :          call get_star_ptr(id, s, ierr)
     977            0 :          if (ierr /= 0) return
     978              : 
     979            0 :          max_model_number = s% max_model_number
     980            0 :          s% max_model_number = max_steps_to_use + s% model_number + 1
     981            0 :          write(*,*) 'relax_angular_momentum: max_steps_to_use', max_steps_to_use
     982              : 
     983            0 :          ipar(1) = num_pts
     984            0 :          ipar(2) = s% max_model_number
     985            0 :          lrpar = 5*num_pts
     986            0 :          allocate(rpar(lrpar), stat=ierr)
     987            0 :          if (ierr /= 0) return
     988              : 
     989            0 :          x(1:num_pts) => rpar(1:num_pts)
     990            0 :          f1(1:4*num_pts) => rpar(num_pts+1:lrpar)
     991            0 :          f(1:4,1:num_pts) => f1(1:4*num_pts)
     992            0 :          call store_rpar(num_pts, ierr)
     993            0 :          if (ierr /= 0) return
     994              : 
     995              :          ! need to use global variables, as relax_angular_momentum uses
     996              :          ! the other_torque routine to which it can't pass rpar
     997            0 :          relax_num_pts = num_pts
     998            0 :          relax_work_array => rpar
     999              : 
    1000            0 :          dxdt_nuc_factor = s% dxdt_nuc_factor
    1001            0 :          s% dxdt_nuc_factor = 0  ! turn off composition change by nuclear burning
    1002            0 :          mix_factor = s% mix_factor
    1003            0 :          s% mix_factor = 0  ! turn off mixing
    1004            0 :          am_D_mix_factor = s% am_D_mix_factor
    1005            0 :          s% am_D_mix_factor = 0d0
    1006            0 :          do_element_diffusion = s% do_element_diffusion
    1007            0 :          s% do_element_diffusion = .false.  ! turn off diffusion
    1008            0 :          starting_dt_next = s% dt_next
    1009            0 :          max_timestep = s% max_timestep
    1010            0 :          s% max_timestep = s% job% max_dt_for_relax_angular_momentum * secyer
    1011            0 :          s% dt_next = min(s% dt_next, s% job% max_dt_for_relax_angular_momentum * secyer)
    1012            0 :          use_other_torque = s% use_other_torque
    1013            0 :          s% use_other_torque = .true.
    1014            0 :          other_torque => s% other_torque
    1015            0 :          s% other_torque => angular_momentum_relax_other_torque
    1016            0 :          time = s% time
    1017            0 :          s% time = 0d0
    1018              : 
    1019              :          call do_internal_evolve( &
    1020              :                id, before_evolve_relax_angular_momentum, &
    1021              :                relax_angular_momentum_adjust_model, relax_angular_momentum_check_model, &
    1022            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    1023              : 
    1024            0 :          s% max_model_number = max_model_number
    1025            0 :          s% dt_next = starting_dt_next
    1026            0 :          s% dxdt_nuc_factor = dxdt_nuc_factor
    1027            0 :          s% mix_factor = mix_factor
    1028            0 :          s% am_D_mix_factor = am_D_mix_factor
    1029            0 :          s% do_element_diffusion = do_element_diffusion
    1030            0 :          s% max_timestep = max_timestep
    1031            0 :          s% use_other_torque = use_other_torque
    1032            0 :          s% other_torque => other_torque
    1033            0 :          s% time = time
    1034              : 
    1035            0 :          call error_check('relax angular momentum',ierr)
    1036              : 
    1037            0 :          deallocate(rpar)
    1038              : 
    1039              : 
    1040              :          contains
    1041              : 
    1042              : 
    1043            0 :          subroutine store_rpar(num_pts, ierr)  ! get interpolation info
    1044              :             use interp_1d_def, only: pm_work_size
    1045              :             use interp_1d_lib, only: interp_pm
    1046              :             integer, intent(in) :: num_pts
    1047              :             integer, intent(out) :: ierr
    1048              :             integer :: op_err
    1049            0 :             real(dp), pointer :: interp_work(:), work(:), p(:)
    1050            0 :             allocate(interp_work(num_pts*pm_work_size), stat=ierr)
    1051            0 :             if (ierr /= 0) return
    1052            0 :             x(:) = xq(:)
    1053              :             op_err = 0
    1054            0 :             f(1,1:num_pts) = angular_momentum(1:num_pts)
    1055              :             work(1:num_pts*pm_work_size) => &
    1056            0 :                interp_work(1:num_pts*pm_work_size)
    1057            0 :             p(1:4*num_pts) => f1(1:4*num_pts)
    1058              :             call interp_pm(x, num_pts, p, pm_work_size, work, &
    1059            0 :                'do_relax_entropy', op_err)
    1060            0 :             if (op_err /= 0) ierr = op_err
    1061            0 :             deallocate(interp_work)
    1062            0 :          end subroutine store_rpar
    1063              : 
    1064              :       end subroutine do_relax_angular_momentum
    1065              : 
    1066            0 :       subroutine before_evolve_relax_angular_momentum(s, id, lipar, ipar, lrpar, rpar, ierr)
    1067              :          type (star_info), pointer :: s
    1068              :          integer, intent(in) :: id, lipar, lrpar
    1069              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1070              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1071              :          integer, intent(out) :: ierr
    1072            0 :          ierr = 0
    1073            0 :          call setup_before_relax(s)
    1074            0 :       end subroutine before_evolve_relax_angular_momentum
    1075              : 
    1076            0 :       integer function relax_angular_momentum_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    1077              :          type (star_info), pointer :: s
    1078              :          integer, intent(in) :: id, lipar, lrpar
    1079              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1080              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1081            0 :          relax_angular_momentum_adjust_model = keep_going
    1082            0 :       end function relax_angular_momentum_adjust_model
    1083              : 
    1084            0 :       integer function relax_angular_momentum_check_model(s, id, lipar, ipar, lrpar, rpar)
    1085              :          use do_one_utils, only: do_bare_bones_check_model
    1086              :          type (star_info), pointer :: s
    1087              :          integer, intent(in) :: id, lipar, lrpar
    1088              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1089              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1090              : 
    1091              :          integer :: num_pts, ierr, max_model_number
    1092              :          real(dp) :: avg_err
    1093            0 :          real(dp), pointer :: x(:)  ! =(num_pts)
    1094            0 :          real(dp), pointer :: f1(:)  ! =(4, num_pts)
    1095              : 
    1096              :          include 'formats'
    1097              : 
    1098            0 :          relax_angular_momentum_check_model = do_bare_bones_check_model(id)
    1099            0 :          if (relax_angular_momentum_check_model /= keep_going) return
    1100              : 
    1101            0 :          if (lipar /= 2) then
    1102            0 :             write(*,*) 'bad lipar for relax_angular_momentum_check_model'
    1103            0 :             relax_angular_momentum_check_model = terminate
    1104            0 :             return
    1105              :          end if
    1106              : 
    1107            0 :          num_pts = ipar(1)
    1108            0 :          max_model_number = ipar(2)
    1109              : 
    1110            0 :          if (lrpar /= 5*num_pts) then
    1111            0 :             write(*,*) 'bad lrpar for relax_angular_momentum_check_model'
    1112            0 :             relax_angular_momentum_check_model = terminate
    1113              :          end if
    1114              : 
    1115              :          ierr = 0
    1116            0 :          x(1:num_pts) => rpar(1:num_pts)
    1117            0 :          f1(1:4*num_pts) => rpar(num_pts+1:lrpar)
    1118            0 :          call adjust_angular_momentum(num_pts, avg_err, ierr)
    1119            0 :          if (ierr /= 0) relax_angular_momentum_check_model = terminate
    1120              : 
    1121            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    1122            0 :             write(*,*) 'relax_angular_momentum avg rel err, dt, model', avg_err, s% dt/secyer, s% model_number
    1123              : 
    1124            0 :          if (s% star_age  >= &
    1125              :             s% job% timescale_for_relax_angular_momentum*&
    1126              :                s% job% num_timescales_for_relax_angular_momentum) then
    1127            0 :             relax_angular_momentum_check_model = terminate
    1128            0 :             s% termination_code = t_relax_finished_okay
    1129            0 :             return
    1130              :          end if
    1131              : 
    1132            0 :          if (s% model_number >= max_model_number) then
    1133            0 :             write(*,*) "Terminated relax because of max_model_number instead of relax_time"
    1134            0 :             relax_angular_momentum_check_model = terminate
    1135            0 :             s% termination_code = t_relax_finished_okay
    1136            0 :             return
    1137              :          end if
    1138              : 
    1139              : 
    1140              :          contains
    1141              : 
    1142              : 
    1143            0 :          subroutine adjust_angular_momentum(num_pts, avg_err, ierr)
    1144              :             use interp_1d_lib, only: interp_values
    1145              :             integer, intent(in) :: num_pts
    1146              :             real(dp), intent(out) :: avg_err
    1147              :             integer, intent(out) :: ierr
    1148              :             integer :: k, nz, op_err
    1149              :             real(dp) :: dangular_momentum_sum
    1150            0 :             real(dp), pointer :: vals(:), xq(:), f(:)
    1151              :             ierr = 0
    1152            0 :             nz = s% nz
    1153            0 :             allocate(vals(nz), xq(nz), stat=ierr)
    1154            0 :             if (ierr /= 0) return
    1155            0 :             xq(1) = s% dq(1)/2  ! xq for cell center
    1156            0 :             do k = 2, nz
    1157            0 :                xq(k) = xq(k-1) + (s% dq(k) + s% dq(k-1))/2
    1158              :             end do
    1159            0 :             dangular_momentum_sum = 0
    1160            0 :             f(1:4*num_pts) => f1(1:4*num_pts)
    1161            0 :             call interp_values(x, num_pts, f, nz, xq, vals(:), op_err)
    1162            0 :             if (op_err /= 0) ierr = op_err
    1163            0 :             dangular_momentum_sum = sum(abs((s% j_rot(1:nz)-vals(1:nz))/vals(1:nz)))
    1164            0 :             avg_err = dangular_momentum_sum/nz
    1165            0 :             deallocate(vals, xq)
    1166            0 :          end subroutine adjust_angular_momentum
    1167              : 
    1168              :       end function relax_angular_momentum_check_model
    1169              : 
    1170            0 :       subroutine angular_momentum_relax_other_torque(id, ierr)
    1171              :          use interp_1d_lib, only: interp_values
    1172              :          integer, intent(in) :: id
    1173              :          integer, intent(out) :: ierr
    1174              :          type (star_info), pointer :: s
    1175              :          integer :: k, k_inner, nz, num_pts, op_err
    1176            0 :          real(dp), pointer :: vals(:), xq(:), x(:), f(:)
    1177              :          real(dp) :: omega_target, j_rot_target
    1178              :          ierr = 0
    1179            0 :          call star_ptr(id, s, ierr)
    1180              : 
    1181            0 :          nz = s% nz
    1182            0 :          num_pts = relax_num_pts
    1183            0 :          allocate(vals(nz), xq(nz), stat=ierr)
    1184            0 :          f(1:4*num_pts) => relax_work_array(num_pts+1:5*num_pts)
    1185            0 :          x(1:num_pts) => relax_work_array(1:num_pts)
    1186            0 :          xq(1) = s% dq(1)/2  ! xq for cell center
    1187            0 :          do k = 2, nz
    1188            0 :             xq(k) = xq(k-1) + (s% dq(k) + s% dq(k-1))/2
    1189              :          end do
    1190            0 :          call interp_values(x, num_pts, f, nz, xq, vals(:), op_err)
    1191            0 :          if (op_err /= 0) ierr = op_err
    1192              : 
    1193            0 :          if (ierr /= 0) return
    1194            0 :          s% extra_jdot(:) = 0d0
    1195            0 :          do k = 1, s% nz
    1196            0 :             if (s% j_rot_flag) then
    1197              :                s% extra_jdot(k) =  &
    1198              :                   (1d0 - exp(-s% dt/(s% job% timescale_for_relax_angular_momentum*secyer))) * &
    1199            0 :                   (vals(k) - s% j_rot_start(k))/s% dt
    1200              :             else
    1201              :                s% extra_jdot(k) =  &
    1202              :                   (1d0 - exp(-s% dt/(s% job% timescale_for_relax_angular_momentum*secyer))) * &
    1203            0 :                   (vals(k) - s% j_rot(k))/s% dt
    1204              :             end if
    1205              :          end do
    1206              :          ! for cells near center use a constant omega, prevents extrapolating j_rot and causing artificially large core rotation
    1207              :          k_inner = -1
    1208            0 :          do k = 2, s% nz
    1209            0 :             if (xq(k) > x(num_pts)) then
    1210            0 :                k_inner = k-1
    1211              :             end if
    1212              :          end do
    1213            0 :          if (s% job% relax_angular_momentum_constant_omega_center) then
    1214            0 :             if (k_inner > 0) then
    1215            0 :                omega_target = vals(k_inner)/s% i_rot(k_inner)% val
    1216            0 :                do k=k_inner+1, s% nz
    1217            0 :                   j_rot_target = omega_target*s% i_rot(k)% val
    1218            0 :                   if (s% j_rot_flag) then
    1219              :                      s% extra_jdot(k) =  &
    1220              :                         (1d0 - exp(-s% dt/(s% job% timescale_for_relax_angular_momentum*secyer))) * &
    1221            0 :                         (j_rot_target - s% j_rot_start(k))/s% dt
    1222              :                   else
    1223              :                      s% extra_jdot(k) =  &
    1224              :                         (1d0 - exp(-s% dt/(s% job% timescale_for_relax_angular_momentum*secyer))) * &
    1225            0 :                         (j_rot_target - s% j_rot(k))/s% dt
    1226              :                   end if
    1227              :                end do
    1228              :             end if
    1229              :          end if
    1230            0 :          deallocate(vals, xq)
    1231            0 :       end subroutine angular_momentum_relax_other_torque
    1232              : 
    1233            0 :       subroutine do_relax_uniform_omega( &
    1234              :             id, kind_of_relax, target_value, num_steps_to_relax_rotation,&
    1235              :             relax_omega_max_yrs_dt, ierr)
    1236              :          integer, intent(in) :: id, kind_of_relax
    1237              :          real(dp), intent(in) :: target_value,relax_omega_max_yrs_dt
    1238              :          integer, intent(in) :: num_steps_to_relax_rotation
    1239              :          integer, intent(out) :: ierr
    1240              : 
    1241              :          integer, parameter :: lipar=3, lrpar=2
    1242              :          integer :: max_model_number, k
    1243              :          real(dp) ::  max_years_for_timestep, mix_factor, dxdt_nuc_factor, am_D_mix_factor
    1244              :          type (star_info), pointer :: s
    1245              :          real(dp), target :: rpar_ary(lrpar)
    1246              :          real(dp), pointer :: rpar(:)
    1247              :          integer, target :: ipar_ary(lipar)
    1248              :          integer, pointer :: ipar(:)
    1249              :          logical :: okay
    1250              : 
    1251              :          include 'formats'
    1252              : 
    1253              :          ierr = 0
    1254              : 
    1255            0 :          rpar => rpar_ary
    1256            0 :          ipar => ipar_ary
    1257              : 
    1258            0 :          call get_star_ptr(id, s, ierr)
    1259            0 :          if (ierr /= 0) return
    1260              : 
    1261            0 :          if (.not. s% rotation_flag) return
    1262              : 
    1263            0 :          rpar(1) = target_value
    1264            0 :          okay = .true.
    1265            0 :          do k=1,s% nz
    1266            0 :             if (s% omega(k) /= target_value) then
    1267              :                okay = .false.
    1268              :                exit
    1269              :             end if
    1270              :          end do
    1271            0 :          if (okay) return
    1272              : 
    1273            0 :          rpar(2) = s% omega(1)
    1274            0 :          ipar(1) = s% model_number
    1275            0 :          ipar(2) = num_steps_to_relax_rotation
    1276            0 :          ipar(3) = kind_of_relax
    1277            0 :          if (num_steps_to_relax_rotation <= 0) then
    1278            0 :             ierr = -1
    1279            0 :             write(*,2) 'invalid num_steps_to_relax_rotation', num_steps_to_relax_rotation
    1280            0 :             return
    1281              :          end if
    1282              : 
    1283            0 :          dxdt_nuc_factor = s% dxdt_nuc_factor
    1284            0 :          s% dxdt_nuc_factor = 0d0  ! turn off composition change by nuclear burning
    1285            0 :          mix_factor = s% mix_factor
    1286            0 :          am_D_mix_factor = s% am_D_mix_factor
    1287            0 :          s% mix_factor = 0d0
    1288            0 :          s% am_D_mix_factor = 0d0
    1289            0 :          max_model_number = s% max_model_number
    1290            0 :          s% max_model_number = num_steps_to_relax_rotation + 1
    1291            0 :          max_years_for_timestep = s% max_years_for_timestep
    1292            0 :          s% max_years_for_timestep = relax_omega_max_yrs_dt
    1293            0 :          write(*,*) 'num_steps_to_relax_rotation', num_steps_to_relax_rotation
    1294              : 
    1295              :          call do_internal_evolve( &
    1296              :                id, before_evolve_relax_omega, &
    1297              :                relax_omega_adjust_model, relax_omega_check_model, &
    1298            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    1299              : 
    1300            0 :          s% dxdt_nuc_factor = dxdt_nuc_factor
    1301            0 :          s% mix_factor = mix_factor
    1302            0 :          s% am_D_mix_factor = am_D_mix_factor
    1303            0 :          s% max_model_number = max_model_number
    1304            0 :          s% max_years_for_timestep = max_years_for_timestep
    1305            0 :          call error_check('relax uniform omega',ierr)
    1306            0 :          s% D_omega(1:s% nz) = 0
    1307            0 :          s% am_nu_rot(1:s% nz) = 0
    1308              : 
    1309              :       end subroutine do_relax_uniform_omega
    1310              : 
    1311              : 
    1312            0 :       subroutine before_evolve_relax_omega(s, id, lipar, ipar, lrpar, rpar, ierr)
    1313              :          type (star_info), pointer :: s
    1314              :          integer, intent(in) :: id, lipar, lrpar
    1315              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1316              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1317              :          integer, intent(out) :: ierr
    1318            0 :          ierr = 0
    1319            0 :          call setup_before_relax(s)
    1320            0 :       end subroutine before_evolve_relax_omega
    1321              : 
    1322            0 :       integer function relax_omega_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    1323              :          type (star_info), pointer :: s
    1324              :          integer, intent(in) :: id, lipar, lrpar
    1325              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1326              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1327            0 :          relax_omega_adjust_model = keep_going
    1328            0 :       end function relax_omega_adjust_model
    1329              : 
    1330            0 :       integer function relax_omega_check_model(s, id, lipar, ipar, lrpar, rpar)
    1331              :          use do_one_utils, only: do_bare_bones_check_model
    1332              :          use hydro_rotation, only: set_uniform_omega, set_i_rot, &
    1333              :             set_surf_avg_rotation_info
    1334              :          type (star_info), pointer :: s
    1335              :          integer, intent(in) :: id, lipar, lrpar
    1336              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1337              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1338              : 
    1339              :          integer :: num_steps_to_use, starting_model_number, kind_of_relax, ierr
    1340              :          real(dp) :: frac, target_value, starting_omega, new_omega, this_step_omega
    1341              : 
    1342              :          include 'formats'
    1343              : 
    1344            0 :          relax_omega_check_model = do_bare_bones_check_model(id)
    1345            0 :          if (relax_omega_check_model /= keep_going) return
    1346              : 
    1347            0 :          starting_model_number = ipar(1)
    1348            0 :          num_steps_to_use = ipar(2)
    1349            0 :          kind_of_relax = ipar(3)
    1350            0 :          target_value = rpar(1)
    1351            0 :          starting_omega = rpar(2)
    1352              : 
    1353              :          frac = max(0d0, min(1d0, &
    1354            0 :             dble(s% model_number - starting_model_number)/dble(num_steps_to_use)))
    1355              : 
    1356            0 :          if (kind_of_relax == relax_to_new_omega) then
    1357            0 :             new_omega = target_value
    1358            0 :          else if (kind_of_relax == relax_to_new_omega_div_omega_crit) then
    1359            0 :             call set_i_rot(s, .false.)
    1360            0 :             call set_surf_avg_rotation_info(s)
    1361            0 :             new_omega = target_value*s% omega_crit_avg_surf
    1362            0 :          else if (kind_of_relax == relax_to_new_surface_rotation_v) then
    1363            0 :             new_omega = target_value*1d5/(s% photosphere_r*Rsun)
    1364              :          else
    1365            0 :             write(*,2) 'bad value for kind_of_relax', kind_of_relax
    1366            0 :             call mesa_error(__FILE__,__LINE__,'relax_omega_check_model')
    1367              :          end if
    1368              : 
    1369            0 :          this_step_omega = frac*new_omega + (1 - frac)*starting_omega
    1370              : 
    1371            0 :          if (s% model_number > starting_model_number + num_steps_to_use + 50 .or. &
    1372              :                abs(s% omega(1) - new_omega) < 1d-4*max(1d-10,abs(new_omega))) then
    1373            0 :             write(*,2) 'final step: wanted-current, current, wanted', &
    1374            0 :                s% model_number, new_omega-s% omega(1), s% omega(1), new_omega
    1375            0 :             relax_omega_check_model = terminate
    1376            0 :             s% termination_code = t_relax_finished_okay
    1377            0 :          else if (mod(s% model_number, s% terminal_interval) == 0) then
    1378            0 :             write(*,2) 'relax to omega: wanted-current, current, wanted', &
    1379            0 :                s% model_number, new_omega-s% omega(1), s% omega(1), new_omega
    1380              :          end if
    1381              : 
    1382              :          ierr = 0
    1383            0 :          call set_uniform_omega(id, this_step_omega, ierr)
    1384            0 :          if (ierr /= 0) then
    1385            0 :             write(*,*) 'set_uniform_omega failed'
    1386            0 :             relax_omega_check_model = terminate
    1387            0 :             return
    1388              :          end if
    1389              : 
    1390              :       end function relax_omega_check_model
    1391              : 
    1392              : 
    1393            0 :       subroutine do_relax_tau_factor(id, new_tau_factor, dlogtau_factor, ierr)
    1394              :          integer, intent(in) :: id
    1395              :          real(dp), intent(in) :: new_tau_factor, dlogtau_factor
    1396              :          integer, intent(out) :: ierr
    1397              :          integer, parameter ::  lipar=1, lrpar=2
    1398              :          integer :: max_model_number
    1399              :          real(dp) :: tau_factor
    1400              :          type (star_info), pointer :: s
    1401              :          integer, target :: ipar_ary(lipar)
    1402              :          integer, pointer :: ipar(:)
    1403              :          real(dp), target :: rpar_ary(lrpar)
    1404              :          real(dp), pointer :: rpar(:)
    1405            0 :          rpar => rpar_ary
    1406            0 :          ipar => ipar_ary
    1407              :          include 'formats'
    1408              :          ierr = 0
    1409            0 :          if (new_tau_factor <= 0) then
    1410            0 :             ierr = -1
    1411            0 :             write(*,*) 'invalid new_tau_factor', new_tau_factor
    1412            0 :             return
    1413              :          end if
    1414            0 :          call get_star_ptr(id, s, ierr)
    1415            0 :          if (ierr /= 0) return
    1416            0 :          tau_factor = s% tau_factor
    1417            0 :          if (abs(new_tau_factor - tau_factor) <= 1d-6) then
    1418            0 :             s% tau_factor = new_tau_factor
    1419            0 :             return
    1420              :          end if
    1421            0 :          write(*,'(A)')
    1422            0 :          write(*,1) 'current tau_factor', tau_factor
    1423            0 :          write(*,1) 'relax to new tau_factor', new_tau_factor
    1424            0 :          write(*,'(A)')
    1425            0 :          write(*,1) 'dlogtau_factor', dlogtau_factor
    1426            0 :          write(*,'(A)')
    1427            0 :          rpar(1) = new_tau_factor
    1428            0 :          rpar(2) = dlogtau_factor
    1429            0 :          max_model_number = s% max_model_number
    1430            0 :          s% max_model_number = -1111
    1431              :          call do_internal_evolve( &
    1432              :                id, before_evolve_relax_tau_factor, &
    1433              :                relax_tau_factor_adjust_model, relax_tau_factor_check_model, &
    1434            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    1435            0 :          s% max_model_number = max_model_number
    1436            0 :          if (ierr == 0) s% force_tau_factor = s% tau_factor
    1437            0 :          call error_check('relax tau factor',ierr)
    1438              :       end subroutine do_relax_tau_factor
    1439              : 
    1440              : 
    1441            0 :       subroutine before_evolve_relax_tau_factor(s, id, lipar, ipar, lrpar, rpar, ierr)
    1442              :          type (star_info), pointer :: s
    1443              :          integer, intent(in) :: id, lipar, lrpar
    1444              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1445              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1446              :          integer, intent(out) :: ierr
    1447            0 :          ierr = 0
    1448            0 :          call turn_off_winds(s)
    1449            0 :          s% max_model_number = -111
    1450            0 :       end subroutine before_evolve_relax_tau_factor
    1451              : 
    1452            0 :       integer function relax_tau_factor_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    1453              :          type (star_info), pointer :: s
    1454              :          integer, intent(in) :: id, lipar, lrpar
    1455              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1456              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1457            0 :          relax_tau_factor_adjust_model = keep_going
    1458            0 :       end function relax_tau_factor_adjust_model
    1459              : 
    1460            0 :       integer function relax_tau_factor_check_model(s, id, lipar, ipar, lrpar, rpar)
    1461              :          use do_one_utils, only:do_bare_bones_check_model
    1462              :          type (star_info), pointer :: s
    1463              :          integer, intent(in) :: id, lipar, lrpar
    1464              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1465              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1466              :          real(dp) :: new_tau_factor, dlogtau_factor, current_tau_factor, next
    1467              :          logical, parameter :: dbg = .false.
    1468              : 
    1469              :          include 'formats'
    1470              : 
    1471            0 :          relax_tau_factor_check_model = do_bare_bones_check_model(id)
    1472            0 :          if (relax_tau_factor_check_model /= keep_going) return
    1473              : 
    1474            0 :          new_tau_factor = rpar(1)
    1475            0 :          dlogtau_factor = rpar(2)
    1476            0 :          current_tau_factor = s% tau_factor
    1477              : 
    1478            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    1479            0 :             write(*,1) 'tau_factor target current', new_tau_factor, current_tau_factor
    1480              : 
    1481            0 :          if (abs(current_tau_factor-new_tau_factor) < 1d-15) then
    1482            0 :             s% tau_factor = new_tau_factor
    1483            0 :             s% termination_code = t_relax_finished_okay
    1484            0 :             relax_tau_factor_check_model = terminate
    1485            0 :             return
    1486              :          end if
    1487              : 
    1488            0 :          if (new_tau_factor < current_tau_factor) then
    1489            0 :             next = exp10(safe_log10(current_tau_factor) - dlogtau_factor)
    1490            0 :             if (next < new_tau_factor) next = new_tau_factor
    1491              :          else
    1492            0 :             next = exp10(safe_log10(current_tau_factor) + dlogtau_factor)
    1493            0 :             if (next > new_tau_factor) next = new_tau_factor
    1494              :          end if
    1495              : 
    1496              :          if (dbg) write(*,1) 'next', next, log10(next)
    1497              : 
    1498            0 :          s% tau_factor = next
    1499            0 :          s% max_timestep = secyer*s% time_step
    1500              : 
    1501            0 :       end function relax_tau_factor_check_model
    1502              : 
    1503              : 
    1504            0 :       subroutine do_relax_opacity_factor(id, new_opacity_factor, dopacity_factor, ierr)
    1505              :          integer, intent(in) :: id
    1506              :          real(dp), intent(in) :: new_opacity_factor, dopacity_factor
    1507              :          integer, intent(out) :: ierr
    1508              :          integer, parameter ::  lipar=1, lrpar=2
    1509              :          integer :: max_model_number
    1510              :          real(dp) :: opacity_factor
    1511              :          type (star_info), pointer :: s
    1512              :          integer, target :: ipar_ary(lipar)
    1513              :          integer, pointer :: ipar(:)
    1514              :          real(dp), target :: rpar_ary(lrpar)
    1515              :          real(dp), pointer :: rpar(:)
    1516            0 :          rpar => rpar_ary
    1517            0 :          ipar => ipar_ary
    1518              :          include 'formats'
    1519              :          ierr = 0
    1520            0 :          if (new_opacity_factor <= 0) then
    1521            0 :             ierr = -1
    1522            0 :             write(*,*) 'invalid new_opacity_factor', new_opacity_factor
    1523            0 :             return
    1524              :          end if
    1525            0 :          call get_star_ptr(id, s, ierr)
    1526            0 :          if (ierr /= 0) return
    1527            0 :          opacity_factor = s% opacity_factor
    1528            0 :          if (abs(new_opacity_factor - opacity_factor) <= 1d-6) then
    1529            0 :             s% opacity_factor = new_opacity_factor
    1530            0 :             return
    1531              :          end if
    1532            0 :          write(*,'(A)')
    1533            0 :          write(*,1) 'current opacity_factor', opacity_factor
    1534            0 :          write(*,1) 'relax to new opacity_factor', new_opacity_factor
    1535            0 :          write(*,'(A)')
    1536            0 :          write(*,1) 'dopacity_factor', dopacity_factor
    1537            0 :          write(*,'(A)')
    1538            0 :          rpar(1) = new_opacity_factor
    1539            0 :          rpar(2) = dopacity_factor
    1540            0 :          max_model_number = s% max_model_number
    1541            0 :          s% max_model_number = -1111
    1542              :          call do_internal_evolve( &
    1543              :                id, before_evolve_relax_opacity_factor, &
    1544              :                relax_opacity_factor_adjust_model, relax_opacity_factor_check_model, &
    1545            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    1546            0 :          s% max_model_number = max_model_number
    1547            0 :          if (ierr == 0) s% force_opacity_factor = s% opacity_factor
    1548            0 :          call error_check('relax opacity factor',ierr)
    1549              :       end subroutine do_relax_opacity_factor
    1550              : 
    1551              : 
    1552            0 :       subroutine before_evolve_relax_opacity_factor(s, id, lipar, ipar, lrpar, rpar, ierr)
    1553              :          type (star_info), pointer :: s
    1554              :          integer, intent(in) :: id, lipar, lrpar
    1555              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1556              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1557              :          integer, intent(out) :: ierr
    1558            0 :          ierr = 0
    1559            0 :          call turn_off_winds(s)
    1560            0 :          s% max_model_number = -111
    1561            0 :       end subroutine before_evolve_relax_opacity_factor
    1562              : 
    1563            0 :       integer function relax_opacity_factor_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    1564              :          type (star_info), pointer :: s
    1565              :          integer, intent(in) :: id, lipar, lrpar
    1566              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1567              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1568            0 :          relax_opacity_factor_adjust_model = keep_going
    1569            0 :       end function relax_opacity_factor_adjust_model
    1570              : 
    1571            0 :       integer function relax_opacity_factor_check_model(s, id, lipar, ipar, lrpar, rpar)
    1572              :          use do_one_utils, only:do_bare_bones_check_model
    1573              :          type (star_info), pointer :: s
    1574              :          integer, intent(in) :: id, lipar, lrpar
    1575              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1576              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1577              :          real(dp) :: new_opacity_factor, dopacity_factor, current_opacity_factor, next
    1578              :          logical, parameter :: dbg = .false.
    1579              : 
    1580              :          include 'formats'
    1581              : 
    1582            0 :          relax_opacity_factor_check_model = do_bare_bones_check_model(id)
    1583            0 :          if (relax_opacity_factor_check_model /= keep_going) return
    1584              : 
    1585            0 :          new_opacity_factor = rpar(1)
    1586            0 :          dopacity_factor = rpar(2)
    1587            0 :          current_opacity_factor = s% opacity_factor
    1588              : 
    1589              :          if (dbg) then
    1590              :             write(*,1) 'new_opacity_factor', new_opacity_factor
    1591              :             write(*,1) 'current_opacity_factor', current_opacity_factor
    1592              :          end if
    1593              : 
    1594            0 :          if (abs(current_opacity_factor-new_opacity_factor) < 1d-15) then
    1595            0 :             s% opacity_factor = new_opacity_factor
    1596            0 :             s% termination_code = t_relax_finished_okay
    1597            0 :             relax_opacity_factor_check_model = terminate
    1598            0 :             return
    1599              :          end if
    1600              : 
    1601            0 :          if (new_opacity_factor < current_opacity_factor) then
    1602            0 :             next = current_opacity_factor - dopacity_factor
    1603            0 :             if (next < new_opacity_factor) next = new_opacity_factor
    1604              :          else
    1605            0 :             next = current_opacity_factor + dopacity_factor
    1606            0 :             if (next > new_opacity_factor) next = new_opacity_factor
    1607              :          end if
    1608              : 
    1609            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    1610            0 :             write(*,1) 'next opacity_factor', next  ! provide terminal feedback to show working.
    1611              : 
    1612            0 :          s% opacity_factor = next
    1613            0 :          s% max_timestep = secyer*s% time_step
    1614              : 
    1615            0 :       end function relax_opacity_factor_check_model
    1616              : 
    1617            0 :       subroutine do_relax_irradiation(id, &
    1618              :             min_steps, new_irrad_flux, new_irrad_col_depth, relax_irradiation_max_yrs_dt, ierr)
    1619              :          integer, intent(in) :: id, min_steps
    1620              :          real(dp), intent(in) :: &
    1621              :             new_irrad_flux, new_irrad_col_depth, relax_irradiation_max_yrs_dt
    1622              :          integer, intent(out) :: ierr
    1623              : 
    1624              :          integer, parameter ::  lipar=2, lrpar=4
    1625              :          integer :: max_model_number, i
    1626              :          real(dp) :: max_years_for_timestep
    1627              :          type (star_info), pointer :: s
    1628              :          logical :: all_same
    1629              :          integer, target :: ipar_ary(lipar)
    1630              :          integer, pointer :: ipar(:)
    1631              :          real(dp), target :: rpar_ary(lrpar)
    1632              :          real(dp), pointer :: rpar(:)
    1633            0 :          rpar => rpar_ary
    1634            0 :          ipar => ipar_ary
    1635              :          include 'formats'
    1636              :          ierr = 0
    1637            0 :          call get_star_ptr(id, s, ierr)
    1638            0 :          if (ierr /= 0) return
    1639              : 
    1640            0 :          ipar(1) = s% model_number
    1641            0 :          ipar(2) = min_steps
    1642              : 
    1643            0 :          rpar(1) = new_irrad_flux
    1644            0 :          rpar(2) = new_irrad_col_depth
    1645            0 :          rpar(3) = s% irradiation_flux
    1646            0 :          rpar(4) = s% column_depth_for_irradiation
    1647              : 
    1648            0 :          all_same = .true.
    1649            0 :          do i = 1, 2
    1650            0 :             if (abs(rpar(i)-rpar(i+2)) > 1d-10) then
    1651              :                all_same = .false.; exit
    1652              :             end if
    1653              :          end do
    1654            0 :          if (all_same) return
    1655              : 
    1656            0 :          write(*,'(A)')
    1657            0 :          write(*,2) 'relax to new irradiation -- min steps', min_steps
    1658            0 :          write(*,'(A)')
    1659              : 
    1660            0 :          max_model_number = s% max_model_number
    1661            0 :          s% max_model_number = -1111
    1662            0 :          max_years_for_timestep = s% max_years_for_timestep
    1663            0 :          s% max_years_for_timestep = relax_irradiation_max_yrs_dt
    1664              :          call do_internal_evolve( &
    1665              :                id, before_evolve_relax_irradiation, &
    1666              :                relax_irradiation_adjust_model, relax_irradiation_check_model, &
    1667            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    1668            0 :          s% max_model_number = max_model_number
    1669            0 :          s% max_years_for_timestep = max_years_for_timestep
    1670            0 :          call error_check('relax irradiation',ierr)
    1671              :       end subroutine do_relax_irradiation
    1672              : 
    1673              : 
    1674            0 :       subroutine before_evolve_relax_irradiation(s, id, lipar, ipar, lrpar, rpar, ierr)
    1675              :          type (star_info), pointer :: s
    1676              :          integer, intent(in) :: id, lipar, lrpar
    1677              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1678              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1679              :          integer, intent(out) :: ierr
    1680            0 :          ierr = 0
    1681            0 :          call turn_off_winds(s)
    1682            0 :          s% max_model_number = -111
    1683            0 :       end subroutine before_evolve_relax_irradiation
    1684              : 
    1685            0 :       integer function relax_irradiation_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    1686              :          type (star_info), pointer :: s
    1687              :          integer, intent(in) :: id, lipar, lrpar
    1688              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1689              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1690            0 :          relax_irradiation_adjust_model = keep_going
    1691            0 :       end function relax_irradiation_adjust_model
    1692              : 
    1693            0 :       integer function relax_irradiation_check_model(s, id, lipar, ipar, lrpar, rpar)
    1694              :          use do_one_utils, only:do_bare_bones_check_model
    1695              :          type (star_info), pointer :: s
    1696              :          integer, intent(in) :: id, lipar, lrpar
    1697              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1698              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1699              : 
    1700              :          integer :: adjust_model, max_num_steps, num_steps
    1701              :          real(dp) :: old_irrad_flux, old_irrad_col_depth
    1702              :          real(dp) :: new_irrad_flux, new_irrad_col_depth, frac
    1703              :          logical, parameter :: dbg = .false.
    1704              : 
    1705              :          include 'formats'
    1706              : 
    1707            0 :          relax_irradiation_check_model = do_bare_bones_check_model(id)
    1708            0 :          if (relax_irradiation_check_model /= keep_going) return
    1709              : 
    1710            0 :          adjust_model = ipar(1)
    1711            0 :          max_num_steps = ipar(2)
    1712              : 
    1713            0 :          new_irrad_flux = rpar(1)
    1714            0 :          new_irrad_col_depth = rpar(2)
    1715            0 :          old_irrad_flux = rpar(3)
    1716            0 :          old_irrad_col_depth = rpar(4)
    1717            0 :          num_steps = s% model_number - adjust_model
    1718            0 :          frac = dble(num_steps)/dble(max_num_steps)
    1719              : 
    1720            0 :          if (s% dt < s% max_years_for_timestep*secyer) then
    1721            0 :             ipar(1) = adjust_model + 1
    1722            0 :             write(*,'(a60,2i6,3x,99e12.3)') 'relax irradiation, model, step, frac, flux, wait for dt', &
    1723            0 :                s% model_number, num_steps, frac, s% irradiation_flux
    1724            0 :             return
    1725              :          end if
    1726              : 
    1727            0 :          if (frac >= 1d0) then
    1728            0 :             s% irradiation_flux = new_irrad_flux
    1729            0 :             s% column_depth_for_irradiation = new_irrad_col_depth
    1730            0 :             relax_irradiation_check_model = terminate
    1731            0 :             s% termination_code = t_relax_finished_okay
    1732              :             write(*,'(a60,2i6,3x,99e12.3)') &
    1733            0 :                'DONE: relax irradiation, model, step, fraction done, flux', &
    1734            0 :                s% model_number, num_steps, frac, s% irradiation_flux
    1735            0 :             return
    1736              :          end if
    1737              : 
    1738              :          s% irradiation_flux = &
    1739            0 :             frac*new_irrad_flux + (1-frac)*old_irrad_flux
    1740              :          s% column_depth_for_irradiation = &
    1741            0 :             frac*new_irrad_col_depth + (1-frac)*old_irrad_col_depth
    1742              : 
    1743            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    1744            0 :             write(*,'(a60,2i6,3x,99e12.3)') 'relax irradiation, model, step, fraction done, flux', &
    1745            0 :                s% model_number, num_steps, frac, s% irradiation_flux
    1746              : 
    1747              :       end function relax_irradiation_check_model
    1748              : 
    1749              : 
    1750            0 :       subroutine do_relax_mass_change( &
    1751              :             id, min_steps, initial_mass_change, final_mass_change, relax_mass_change_max_yrs_dt, ierr)
    1752              :          integer, intent(in) :: id, min_steps
    1753              :          real(dp), intent(in) :: initial_mass_change, final_mass_change, relax_mass_change_max_yrs_dt
    1754              :          integer, intent(out) :: ierr
    1755              : 
    1756              :          integer, parameter ::  lipar=2, lrpar=2
    1757              :          integer :: max_model_number
    1758              :          real(dp) :: max_years_for_timestep
    1759              :          type (star_info), pointer :: s
    1760              :          integer, target :: ipar_ary(lipar)
    1761              :          integer, pointer :: ipar(:)
    1762              :          real(dp), target :: rpar_ary(lrpar)
    1763              :          real(dp), pointer :: rpar(:)
    1764              : 
    1765            0 :          rpar => rpar_ary
    1766            0 :          ipar => ipar_ary
    1767              :          include 'formats'
    1768              : 
    1769            0 :          ierr = 0
    1770            0 :          if (abs(initial_mass_change - final_mass_change) < 1d-10) return
    1771              : 
    1772            0 :          call get_star_ptr(id, s, ierr)
    1773            0 :          if (ierr /= 0) return
    1774              : 
    1775              : 
    1776            0 :          ipar(1) = s% model_number
    1777            0 :          ipar(2) = min_steps
    1778            0 :          rpar(1) = initial_mass_change
    1779            0 :          rpar(2) = final_mass_change
    1780              : 
    1781            0 :          write(*,'(A)')
    1782            0 :          write(*,2) 'relax_mass_change -- min steps, init, final, max dt', &
    1783            0 :             min_steps, initial_mass_change, final_mass_change, relax_mass_change_max_yrs_dt
    1784            0 :          write(*,'(A)')
    1785              : 
    1786            0 :          max_model_number = s% max_model_number
    1787            0 :          s% max_model_number = -1111
    1788            0 :          max_years_for_timestep = s% max_years_for_timestep
    1789            0 :          s% max_years_for_timestep = relax_mass_change_max_yrs_dt
    1790              : 
    1791              :          call do_internal_evolve( &
    1792              :                id, before_evolve_relax_mass_change, &
    1793              :                relax_mass_change_adjust_model, relax_mass_change_check_model, &
    1794            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    1795              : 
    1796            0 :          s% max_model_number = max_model_number
    1797            0 :          s% max_years_for_timestep = max_years_for_timestep
    1798              : 
    1799            0 :          if (ierr == 0) s% mass_change = final_mass_change
    1800              : 
    1801            0 :          call error_check('relax mass change',ierr)
    1802              : 
    1803              :       end subroutine do_relax_mass_change
    1804              : 
    1805              : 
    1806            0 :       subroutine before_evolve_relax_mass_change(s, id, lipar, ipar, lrpar, rpar, ierr)
    1807              :          type (star_info), pointer :: s
    1808              :          integer, intent(in) :: id, lipar, lrpar
    1809              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1810              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1811              :          integer, intent(out) :: ierr
    1812            0 :          ierr = 0
    1813            0 :          call turn_off_winds(s)
    1814            0 :          s% max_model_number = -111
    1815            0 :       end subroutine before_evolve_relax_mass_change
    1816              : 
    1817            0 :       integer function relax_mass_change_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    1818              :          type (star_info), pointer :: s
    1819              :          integer, intent(in) :: id, lipar, lrpar
    1820              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1821              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1822            0 :          relax_mass_change_adjust_model = keep_going
    1823            0 :       end function relax_mass_change_adjust_model
    1824              : 
    1825            0 :       integer function relax_mass_change_check_model(s, id, lipar, ipar, lrpar, rpar)
    1826              :          use do_one_utils, only:do_bare_bones_check_model
    1827              :          type (star_info), pointer :: s
    1828              :          integer, intent(in) :: id, lipar, lrpar
    1829              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1830              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1831              : 
    1832              :          integer :: adjust_model, max_num_steps, num_steps
    1833              :          real(dp) :: init_mass_change, final_mass_change, frac
    1834              :          logical, parameter :: dbg = .false.
    1835              : 
    1836              :          include 'formats'
    1837              : 
    1838            0 :          relax_mass_change_check_model = do_bare_bones_check_model(id)
    1839            0 :          if (relax_mass_change_check_model /= keep_going) return
    1840              : 
    1841            0 :          adjust_model = ipar(1)
    1842            0 :          max_num_steps = ipar(2)
    1843            0 :          num_steps = s% model_number - adjust_model
    1844              : 
    1845            0 :          init_mass_change = rpar(1)
    1846            0 :          final_mass_change = rpar(2)
    1847            0 :          frac = dble(num_steps)/dble(max_num_steps)
    1848              : 
    1849            0 :          if (s% dt < s% max_years_for_timestep*secyer) then
    1850            0 :             ipar(1) = adjust_model + 1  ! don't count this one
    1851            0 :             write(*,'(a60,2i6,3x,99e12.3)') 'relax_mass_change wait for dt: model, step, frac', &
    1852            0 :                s% model_number, num_steps, frac
    1853            0 :             return
    1854              :          end if
    1855              : 
    1856            0 :          if (frac >= 1d0) then
    1857            0 :             s% mass_change = final_mass_change
    1858            0 :             relax_mass_change_check_model = terminate
    1859            0 :             s% termination_code = t_relax_finished_okay
    1860            0 :             write(*,'(a60,2i6,3x,99e12.3)') 'DONE: relax_mass_change'
    1861            0 :             return
    1862              :          end if
    1863              : 
    1864            0 :          s% mass_change = frac*final_mass_change + (1-frac)*init_mass_change
    1865              : 
    1866            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    1867            0 :             write(*,'(a60,2i6,3x,99e12.3)') 'relax_mass_change, model, step, fraction done, mass_change', &
    1868            0 :                s% model_number, num_steps, frac, s% mass_change
    1869              : 
    1870              :       end function relax_mass_change_check_model
    1871              : 
    1872              : 
    1873            0 :       subroutine do_relax_core( &
    1874              :             id, new_core_mass, dlg_core_mass_per_step, &
    1875              :             relax_core_years_for_dt, core_avg_rho, core_avg_eps, ierr)
    1876              :          integer, intent(in) :: id
    1877              :          real(dp), intent(in) :: new_core_mass  ! in Msun units
    1878              :          real(dp), intent(in) :: dlg_core_mass_per_step, relax_core_years_for_dt
    1879              :          real(dp), intent(in) :: core_avg_rho, core_avg_eps
    1880              :             ! adjust R_center according to core_avg_rho (g cm^-3)
    1881              :             ! adjust L_center according to core_avg_eps (erg g^-1 s^-1)
    1882              :          integer, intent(out) :: ierr
    1883              : 
    1884              :          integer, parameter ::  lipar=1, lrpar=5
    1885              :          integer :: max_model_number
    1886              :          real(dp) :: max_years_for_timestep
    1887              :          real(dp) :: current_core_mass
    1888              :          type (star_info), pointer :: s
    1889              :          integer, target :: ipar_ary(lipar)
    1890              :          integer, pointer :: ipar(:)
    1891              :          real(dp), target :: rpar_ary(lrpar)
    1892              :          real(dp), pointer :: rpar(:)
    1893            0 :          rpar => rpar_ary
    1894            0 :          ipar => ipar_ary
    1895              :          include 'formats'
    1896              :          ierr = 0
    1897            0 :          if (new_core_mass <= 0) then
    1898            0 :             ierr = -1
    1899            0 :             write(*,*) 'invalid new_core_mass', new_core_mass
    1900            0 :             return
    1901              :          end if
    1902            0 :          call get_star_ptr(id, s, ierr)
    1903            0 :          if (ierr /= 0) return
    1904            0 :          current_core_mass = s% M_center/Msun
    1905            0 :          if (abs(new_core_mass - current_core_mass) <= 1d-12*new_core_mass) then
    1906            0 :             call do1_relax_core(s, new_core_mass, core_avg_rho, core_avg_eps, ierr)
    1907            0 :             if (ierr /= 0) then
    1908            0 :                write(*,*) 'failed in do1_relax_core'
    1909              :             end if
    1910            0 :             return
    1911              :          end if
    1912            0 :          write(*,'(A)')
    1913            0 :          write(*,1) 'current core mass', current_core_mass
    1914            0 :          write(*,1) 'relax to new_core_mass', new_core_mass
    1915            0 :          write(*,'(A)')
    1916            0 :          write(*,1) 'dlg_core_mass_per_step', dlg_core_mass_per_step
    1917            0 :          write(*,'(A)')
    1918            0 :          rpar(1) = new_core_mass
    1919            0 :          rpar(2) = dlg_core_mass_per_step
    1920            0 :          rpar(3) = relax_core_years_for_dt
    1921            0 :          rpar(4) = core_avg_rho
    1922            0 :          rpar(5) = core_avg_eps
    1923            0 :          max_model_number = s% max_model_number
    1924            0 :          s% max_model_number = -1111
    1925            0 :          max_years_for_timestep = s% max_years_for_timestep
    1926            0 :          s% max_years_for_timestep = relax_core_years_for_dt
    1927              :          call do_internal_evolve( &
    1928              :                id, before_evolve_relax_core, relax_core_adjust_model, &
    1929              :                relax_core_check_model, null_finish_model,  &
    1930            0 :                .true., lipar, ipar, lrpar, rpar, ierr)
    1931            0 :          s% max_model_number = max_model_number
    1932            0 :          s% max_years_for_timestep = max_years_for_timestep
    1933            0 :          call error_check('relax core',ierr)
    1934              :       end subroutine do_relax_core
    1935              : 
    1936              : 
    1937            0 :       subroutine before_evolve_relax_core(s, id, lipar, ipar, lrpar, rpar, ierr)
    1938              :          type (star_info), pointer :: s
    1939              :          integer, intent(in) :: id, lipar, lrpar
    1940              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1941              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1942              :          integer, intent(out) :: ierr
    1943              :          real(dp) :: relax_core_years_for_dt
    1944            0 :          ierr = 0
    1945            0 :          call setup_before_relax(s)
    1946            0 :          s% max_model_number = -111
    1947            0 :          relax_core_years_for_dt = rpar(3)
    1948            0 :          s% dt_next = secyer*relax_core_years_for_dt
    1949            0 :       end subroutine before_evolve_relax_core
    1950              : 
    1951            0 :       integer function relax_core_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    1952              :          type (star_info), pointer :: s
    1953              :          integer, intent(in) :: id, lipar, lrpar
    1954              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1955              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1956            0 :          relax_core_adjust_model = keep_going
    1957            0 :       end function relax_core_adjust_model
    1958              : 
    1959            0 :       integer function relax_core_check_model(s, id, lipar, ipar, lrpar, rpar)
    1960              :          use do_one_utils, only:do_bare_bones_check_model
    1961              :          type (star_info), pointer :: s
    1962              :          integer, intent(in) :: id, lipar, lrpar
    1963              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    1964              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    1965              :          real(dp) :: new_core_mass, dlg_core_mass_per_step, next
    1966              :          real(dp) :: relax_core_dt, relax_core_years_for_dt
    1967              :          real(dp) :: core_avg_rho, core_avg_eps, current_core_mass
    1968              :          integer :: ierr
    1969              :          logical :: end_now
    1970              : 
    1971              :          logical, parameter :: dbg = .false.
    1972              : 
    1973              :          include 'formats'
    1974              : 
    1975            0 :          relax_core_check_model = do_bare_bones_check_model(id)
    1976            0 :          if (relax_core_check_model /= keep_going) return
    1977              : 
    1978            0 :          new_core_mass = rpar(1)
    1979            0 :          dlg_core_mass_per_step = rpar(2)
    1980            0 :          relax_core_years_for_dt = rpar(3)
    1981            0 :          core_avg_rho = rpar(4)
    1982            0 :          core_avg_eps = rpar(5)
    1983              :          ierr = 0
    1984              : 
    1985            0 :          current_core_mass = s% M_center/Msun
    1986            0 :          if (abs(new_core_mass - current_core_mass) <= 1d-12*new_core_mass) then
    1987            0 :             call do1_relax_core(s, new_core_mass, core_avg_rho, core_avg_eps, ierr)
    1988            0 :             if (ierr /= 0) then
    1989            0 :                write(*,*) 'failed in do1_relax_core'
    1990              :             end if
    1991            0 :             relax_core_check_model = terminate
    1992            0 :             s% termination_code = t_relax_finished_okay
    1993            0 :             return
    1994              :          end if
    1995              : 
    1996            0 :          if (mod(s% model_number, s% terminal_interval) == 0) then
    1997            0 :             write(*,1) 'current & target core masses', &
    1998            0 :                current_core_mass, new_core_mass, &
    1999            0 :                (new_core_mass - current_core_mass)/new_core_mass
    2000              :          end if
    2001              : 
    2002            0 :          relax_core_dt = secyer*relax_core_years_for_dt
    2003              : 
    2004            0 :          if (s% dt < relax_core_dt*0.9d0) then
    2005            0 :             write(*,1) 's% dt < relax_core_dt*0.9d0', s% dt, relax_core_dt*0.9d0
    2006            0 :             write(*,1) 's% max_timestep', s% max_timestep
    2007            0 :             write(*,1) 's% max_years_for_timestep*secyer', s% max_years_for_timestep*secyer
    2008            0 :             write(*,'(A)')
    2009            0 :             return  ! give a chance to stabilize
    2010              :          end if
    2011              : 
    2012            0 :          end_now=.false.
    2013            0 :          if (new_core_mass < current_core_mass) then
    2014            0 :             next = exp10(safe_log10(current_core_mass) - dlg_core_mass_per_step)
    2015            0 :             if (next < new_core_mass) then
    2016            0 :                next = new_core_mass
    2017            0 :                end_now = .true.
    2018              :             end if
    2019              :          else
    2020            0 :             next = exp10(log10(max(1d-8,current_core_mass)) + dlg_core_mass_per_step)
    2021            0 :             if (next > new_core_mass) then
    2022            0 :                next = new_core_mass
    2023            0 :                end_now = .true.
    2024              :             end if
    2025              :          end if
    2026              : 
    2027              :          if (dbg) write(*,1) 'next', next, log10(next)
    2028              : 
    2029            0 :          call do1_relax_core(s, next, core_avg_rho, core_avg_eps, ierr)
    2030            0 :          if (ierr /= 0) then
    2031            0 :             write(*,*) 'failed in do1_relax_core'
    2032            0 :             relax_core_check_model = terminate
    2033              :          end if
    2034              : 
    2035              :          if (.true.) then
    2036            0 :             write(*,1) 's% M_center', s% M_center
    2037            0 :             write(*,1) 's% L_center', s% L_center
    2038            0 :             write(*,1) 's% R_center', s% R_center
    2039            0 :             write(*,1) 's% xmstar', s% xmstar
    2040            0 :             write(*,'(A)')
    2041              :          end if
    2042              : 
    2043            0 :          if(end_now) then
    2044            0 :             relax_core_check_model = terminate
    2045            0 :             s% termination_code = t_relax_finished_okay
    2046            0 :             return
    2047              :          end if
    2048              : 
    2049              :       end function relax_core_check_model
    2050              : 
    2051              : 
    2052            0 :       subroutine do1_relax_core(s, next, core_avg_rho, core_avg_eps, ierr)
    2053              :          type (star_info), pointer :: s
    2054              :          real(dp), intent(in) :: next, core_avg_rho, core_avg_eps
    2055              :          integer, intent(out) :: ierr
    2056              :          real(dp) :: next_M_center, next_R_center, next_L_center
    2057            0 :          ierr = 0
    2058            0 :          next_M_center = next*Msun
    2059            0 :          s% M_center = next_M_center
    2060            0 :          s% xmstar = s% mstar - s% M_center
    2061            0 :          next_R_center = pow(s% M_center/(core_avg_rho*four_thirds_pi),one_third)
    2062            0 :          call do1_relax_R_center(s, next_R_center, ierr)
    2063            0 :          if (ierr /= 0) return
    2064            0 :          next_L_center = s% M_center*core_avg_eps
    2065            0 :          call do1_relax_L_center(s, next_L_center, ierr)
    2066              :       end subroutine do1_relax_core
    2067              : 
    2068              : 
    2069            0 :       subroutine do_relax_mass_scale( &
    2070              :             id, new_mass, dlgm_per_step, change_mass_years_for_dt, ierr)
    2071              :          integer, intent(in) :: id
    2072              :          real(dp), intent(in) :: new_mass, dlgm_per_step, change_mass_years_for_dt
    2073              :          integer, intent(out) :: ierr
    2074              :          integer, parameter ::  lipar=1, lrpar=3
    2075              :          integer :: max_model_number
    2076              :          real(dp) :: max_years_for_timestep, relax_mass_scale_dt, eps_mdot_factor
    2077              :          logical :: adding_mass
    2078              :          type (star_info), pointer :: s
    2079              :          integer, target :: ipar_ary(lipar)
    2080              :          integer, pointer :: ipar(:)
    2081              :          real(dp), target :: rpar_ary(lrpar)
    2082              :          real(dp), pointer :: rpar(:)
    2083            0 :          rpar => rpar_ary
    2084            0 :          ipar => ipar_ary
    2085              :          include 'formats'
    2086              :          ierr = 0
    2087            0 :          if (new_mass <= 0) then
    2088            0 :             ierr = -1
    2089            0 :             write(*,*) 'invalid new_mass', new_mass
    2090            0 :             return
    2091              :          end if
    2092            0 :          call get_star_ptr(id, s, ierr)
    2093            0 :          if (ierr /= 0) return
    2094            0 :          if (abs(new_mass - s% star_mass) <= 1d-12*new_mass) then
    2095            0 :             s% star_mass = new_mass
    2096            0 :             s% mstar = new_mass*Msun
    2097            0 :             s% xmstar = s% mstar - s% M_center
    2098            0 :             return
    2099              :          end if
    2100            0 :          write(*,'(A)')
    2101            0 :          write(*,1) 'relax_mass_scale'
    2102            0 :          write(*,1) 'current star_mass', s% star_mass
    2103            0 :          write(*,1) 'relax to new_mass', new_mass
    2104            0 :          write(*,1) 'dlgm_per_step', dlgm_per_step
    2105            0 :          write(*,'(A)')
    2106            0 :          rpar(1) = new_mass
    2107            0 :          rpar(2) = dlgm_per_step
    2108            0 :          rpar(3) = change_mass_years_for_dt
    2109            0 :          max_model_number = s% max_model_number
    2110            0 :          s% max_model_number = -1111
    2111              : 
    2112            0 :          adding_mass = (new_mass > s% star_mass)
    2113              : 
    2114            0 :          eps_mdot_factor = s% eps_mdot_factor
    2115            0 :          s% eps_mdot_factor = 0
    2116              : 
    2117            0 :          max_years_for_timestep = s% max_years_for_timestep
    2118            0 :          relax_mass_scale_dt = secyer*change_mass_years_for_dt
    2119            0 :          s% max_years_for_timestep = relax_mass_scale_dt/secyer
    2120              :          call do_internal_evolve( &
    2121              :                id, before_evolve_relax_mass_scale, &
    2122              :                relax_mass_scale_adjust_model, relax_mass_scale_check_model, null_finish_model, &
    2123            0 :                .true., lipar, ipar, lrpar, rpar, ierr)
    2124            0 :          s% max_model_number = max_model_number
    2125            0 :          s% star_mass = new_mass
    2126            0 :          s% mstar = new_mass*Msun
    2127            0 :          s% xmstar = s% mstar - s% M_center
    2128            0 :          s% eps_mdot_factor = eps_mdot_factor
    2129            0 :          s% max_years_for_timestep = max_years_for_timestep
    2130              : 
    2131            0 :          call error_check('relax mass scale',ierr)
    2132              :       end subroutine do_relax_mass_scale
    2133              : 
    2134              : 
    2135            0 :       subroutine before_evolve_relax_mass_scale(s, id, lipar, ipar, lrpar, rpar, ierr)
    2136              :          type (star_info), pointer :: s
    2137              :          integer, intent(in) :: id, lipar, lrpar
    2138              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2139              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2140              :          integer, intent(out) :: ierr
    2141              :          real(dp) :: change_mass_years_for_dt
    2142            0 :          ierr = 0
    2143            0 :          call setup_before_relax(s)
    2144            0 :          s% max_model_number = -111
    2145            0 :          change_mass_years_for_dt = rpar(3)
    2146            0 :          s% dt_next = secyer*change_mass_years_for_dt
    2147            0 :       end subroutine before_evolve_relax_mass_scale
    2148              : 
    2149            0 :       integer function relax_mass_scale_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    2150              :          type (star_info), pointer :: s
    2151              :          integer, intent(in) :: id, lipar, lrpar
    2152              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2153              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2154            0 :          relax_mass_scale_adjust_model = keep_going
    2155            0 :       end function relax_mass_scale_adjust_model
    2156              : 
    2157            0 :       integer function relax_mass_scale_check_model(s, id, lipar, ipar, lrpar, rpar)
    2158              :          use do_one_utils, only:do_bare_bones_check_model
    2159              :          type (star_info), pointer :: s
    2160              :          integer, intent(in) :: id, lipar, lrpar
    2161              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2162              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2163              :          real(dp) :: new_mass, dlgm_per_step, next
    2164              :          real(dp) :: relax_mass_scale_dt, change_mass_years_for_dt
    2165              :          logical, parameter :: dbg = .false.
    2166              : 
    2167              :          include 'formats'
    2168              : 
    2169            0 :          relax_mass_scale_check_model = do_bare_bones_check_model(id)
    2170            0 :          if (relax_mass_scale_check_model /= keep_going) return
    2171              : 
    2172            0 :          new_mass = rpar(1)
    2173            0 :          dlgm_per_step = rpar(2)
    2174            0 :          change_mass_years_for_dt = rpar(3)
    2175            0 :          if (s% star_mass < 0.01d0) dlgm_per_step = dlgm_per_step*0.1d0
    2176              :          !if (s% star_mass < 0.001d0) dlgm_per_step = dlgm_per_step*0.1d0
    2177              : 
    2178              :          if (dbg) then
    2179              :             write(*,1) 'new_mass', new_mass
    2180              :             write(*,1) 'current mass', s% star_mass
    2181              :          end if
    2182              : 
    2183            0 :          if (abs(s% star_mass-new_mass) < 1d-12*new_mass) then
    2184            0 :             s% star_mass = new_mass
    2185            0 :             s% mstar = new_mass*Msun
    2186            0 :             s% xmstar = s% mstar - s% M_center
    2187            0 :             s% termination_code = t_relax_finished_okay
    2188            0 :             relax_mass_scale_check_model = terminate
    2189            0 :             return
    2190              :          end if
    2191              : 
    2192            0 :          relax_mass_scale_dt = secyer*change_mass_years_for_dt
    2193              : 
    2194            0 :          if (s% dt < relax_mass_scale_dt*0.9d0) return  ! give a chance to stabilize
    2195              : 
    2196            0 :          if (new_mass < s% star_mass) then
    2197            0 :             next = exp10(safe_log10(s% star_mass) - dlgm_per_step)
    2198            0 :             if (next < new_mass) next = new_mass
    2199              :          else
    2200            0 :             next = exp10(safe_log10(s% star_mass) + dlgm_per_step)
    2201            0 :             if (next > new_mass) next = new_mass
    2202              :          end if
    2203              : 
    2204              :          if (dbg) write(*,1) 'next', next, log10(next)
    2205              : 
    2206            0 :          s% star_mass = next
    2207            0 :          s% mstar = next*Msun
    2208            0 :          s% xmstar = s% mstar - s% M_center
    2209              : 
    2210            0 :       end function relax_mass_scale_check_model
    2211              : 
    2212              : 
    2213            0 :       subroutine do_relax_M_center(id, new_mass, dlgm_per_step, relax_M_center_dt, ierr)
    2214              :          integer, intent(in) :: id
    2215              :          real(dp), intent(in) :: new_mass, dlgm_per_step, relax_M_center_dt
    2216              :          integer, intent(out) :: ierr
    2217              :          integer, parameter ::  lipar=1, lrpar=3
    2218              :          integer :: max_model_number
    2219              :          real(dp) :: max_years_for_timestep
    2220              :          type (star_info), pointer :: s
    2221              :          integer, target :: ipar_ary(lipar)
    2222              :          integer, pointer :: ipar(:)
    2223              :          real(dp), target :: rpar_ary(lrpar)
    2224              :          real(dp), pointer :: rpar(:)
    2225            0 :          rpar => rpar_ary
    2226            0 :          ipar => ipar_ary
    2227              :          include 'formats'
    2228              :          ierr = 0
    2229            0 :          if (new_mass <= 0) then
    2230            0 :             ierr = -1
    2231            0 :             write(*,*) 'invalid new_mass', new_mass
    2232            0 :             return
    2233              :          end if
    2234            0 :          call get_star_ptr(id, s, ierr)
    2235            0 :          if (ierr /= 0) return
    2236            0 :          if (abs(new_mass - s% star_mass) <= 1d-6) then
    2237            0 :             s% star_mass = new_mass
    2238            0 :             s% mstar = new_mass*Msun
    2239            0 :             s% xmstar = s% mstar - s% M_center
    2240            0 :             return
    2241              :          end if
    2242            0 :          write(*,'(A)')
    2243            0 :          write(*,1) 'current star_mass', s% star_mass
    2244            0 :          write(*,1) 'relax to new_mass', new_mass
    2245            0 :          write(*,'(A)')
    2246            0 :          write(*,1) 'dlgm_per_step', dlgm_per_step
    2247            0 :          write(*,'(A)')
    2248            0 :          rpar(1) = new_mass
    2249            0 :          rpar(2) = dlgm_per_step
    2250            0 :          rpar(3) = relax_M_center_dt
    2251            0 :          max_model_number = s% max_model_number
    2252            0 :          max_years_for_timestep = s% max_years_for_timestep
    2253            0 :          s% max_model_number = -1111
    2254            0 :          s% max_years_for_timestep = relax_M_center_dt/secyer
    2255              :          call do_internal_evolve( &
    2256              :                id, before_evolve_relax_M_center, &
    2257              :                relax_M_center_adjust_model, relax_M_center_check_model, &
    2258            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    2259              : 
    2260            0 :          s% max_model_number = max_model_number
    2261            0 :          s% max_years_for_timestep = max_years_for_timestep
    2262            0 :          call error_check('relax M center',ierr)
    2263              :       end subroutine do_relax_M_center
    2264              : 
    2265              : 
    2266            0 :       subroutine before_evolve_relax_M_center(s, id, lipar, ipar, lrpar, rpar, ierr)
    2267              :          type (star_info), pointer :: s
    2268              :          integer, intent(in) :: id, lipar, lrpar
    2269              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2270              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2271              :          integer, intent(out) :: ierr
    2272            0 :          ierr = 0
    2273            0 :          call setup_before_relax(s)
    2274            0 :          s% max_model_number = -111
    2275            0 :          s% dt_next =  rpar(3)  ! relax_M_center_dt
    2276            0 :       end subroutine before_evolve_relax_M_center
    2277              : 
    2278            0 :       integer function relax_M_center_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    2279              :          type (star_info), pointer :: s
    2280              :          integer, intent(in) :: id, lipar, lrpar
    2281              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2282              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2283            0 :          relax_M_center_adjust_model = keep_going
    2284            0 :       end function relax_M_center_adjust_model
    2285              : 
    2286            0 :       integer function relax_M_center_check_model(s, id, lipar, ipar, lrpar, rpar)
    2287              :          use do_one_utils, only:do_bare_bones_check_model
    2288              :          type (star_info), pointer :: s
    2289              :          integer, intent(in) :: id, lipar, lrpar
    2290              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2291              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2292              :          integer :: ierr
    2293              :          real(dp) :: new_mass, dlgm_per_step, relax_M_center_dt, next
    2294              :          logical, parameter :: dbg = .false.
    2295              :          logical :: end_now
    2296              : 
    2297              :          include 'formats'
    2298              : 
    2299            0 :          relax_M_center_check_model = do_bare_bones_check_model(id)
    2300            0 :          if (relax_M_center_check_model /= keep_going) return
    2301              : 
    2302            0 :          new_mass = rpar(1)
    2303            0 :          dlgm_per_step = rpar(2)
    2304            0 :          relax_M_center_dt = rpar(3)
    2305              : 
    2306            0 :          if (mod(s% model_number, s% terminal_interval) == 0 .and. s% M_center>0.0d0) &
    2307            0 :             write(*,1) 'relax_M_center target/current', new_mass/(s% M_center/Msun)
    2308              : 
    2309            0 :          end_now=.false.
    2310            0 :          if (new_mass < s% star_mass) then
    2311            0 :             next = exp10(safe_log10(s% star_mass) - dlgm_per_step)
    2312            0 :             if (next < new_mass) then
    2313            0 :                next = new_mass
    2314            0 :                end_now=.true.
    2315              :             end if
    2316              :          else
    2317            0 :             next = exp10(safe_log10(s% star_mass) + dlgm_per_step)
    2318            0 :             if (next > new_mass) then
    2319            0 :                next = new_mass
    2320            0 :                end_now=.true.
    2321              :             end if
    2322              :          end if
    2323              : 
    2324            0 :          if (abs(s% star_mass - new_mass) < 1d-15 .or. end_now) then
    2325            0 :             call set_new_mass_for_relax_M_center(s, new_mass, ierr)
    2326              :             if (ierr /= 0) then
    2327              :                write(*,*) 'failed to set mass for relax_M_center'
    2328              :                relax_M_center_check_model = terminate
    2329              :                return
    2330              :             end if
    2331            0 :             write(*,1) 'final mass', s% star_mass, s% mstar, s% M_center, s% xmstar
    2332            0 :             relax_M_center_check_model = terminate
    2333            0 :             s% termination_code = t_relax_finished_okay
    2334            0 :             return
    2335              :          end if
    2336              : 
    2337            0 :          if (s% dt < relax_M_center_dt*0.9d0) return  ! give a chance to stabilize
    2338              : 
    2339              :          if (dbg) write(*,1) 'next', next, log10(next)
    2340              : 
    2341            0 :          call set_new_mass_for_relax_M_center(s, next, ierr)
    2342              :          if (ierr /= 0) then
    2343              :             write(*,*) 'failed to set mass for relax_M_center'
    2344              :             relax_M_center_check_model = terminate
    2345              :             return
    2346              :          end if
    2347              : 
    2348            0 :       end function relax_M_center_check_model
    2349              : 
    2350              : 
    2351            0 :       subroutine set_new_mass_for_relax_M_center(s, new_mass, ierr)
    2352              :          use star_utils, only: set_qs
    2353              :          type (star_info), pointer :: s
    2354              :          real(dp), intent(in) :: new_mass  ! Msun
    2355              :          integer, intent(out) :: ierr
    2356              :          include 'formats'
    2357            0 :          ierr = 0
    2358            0 :          s% star_mass = new_mass
    2359            0 :          s% mstar = new_mass*Msun
    2360            0 :          s% M_center = s% mstar - s% xmstar
    2361              :       end subroutine set_new_mass_for_relax_M_center
    2362              : 
    2363              : 
    2364            0 :       subroutine do_relax_R_center(id, new_R_center, dlgR_per_step, relax_R_center_dt, ierr)
    2365              :          integer, intent(in) :: id
    2366              :          real(dp), intent(in) :: new_R_center, dlgR_per_step, relax_R_center_dt
    2367              :          integer, intent(out) :: ierr
    2368              :          integer, parameter ::  lipar=1, lrpar=3
    2369              :          integer :: max_model_number
    2370              :          real(dp) :: max_years_for_timestep
    2371              :          type (star_info), pointer :: s
    2372              :          integer, target :: ipar_ary(lipar)
    2373              :          integer, pointer :: ipar(:)
    2374              :          real(dp), target :: rpar_ary(lrpar)
    2375              :          real(dp), pointer :: rpar(:)
    2376            0 :          rpar => rpar_ary
    2377            0 :          ipar => ipar_ary
    2378              :          include 'formats'
    2379              :          ierr = 0
    2380            0 :          if (new_R_center < 0) then
    2381            0 :             ierr = -1
    2382            0 :             write(*,*) 'invalid new_R_center', new_R_center
    2383            0 :             return
    2384              :          end if
    2385            0 :          call get_star_ptr(id, s, ierr)
    2386            0 :          if (ierr /= 0) return
    2387            0 :          if (abs(new_R_center - s% R_center) <= 1d-6) then
    2388            0 :             s% R_center = new_R_center
    2389            0 :             return
    2390              :          end if
    2391            0 :          write(*,'(A)')
    2392            0 :          write(*,1) 'current R_center', s% R_center
    2393            0 :          write(*,1) 'relax to new_R_center', new_R_center
    2394            0 :          write(*,'(A)')
    2395            0 :          write(*,1) 'dlgR_per_step', dlgR_per_step
    2396            0 :          write(*,'(A)')
    2397            0 :          rpar(1) = new_R_center
    2398            0 :          rpar(2) = dlgR_per_step
    2399            0 :          rpar(3) = relax_R_center_dt
    2400            0 :          max_model_number = s% max_model_number
    2401            0 :          max_years_for_timestep = s% max_years_for_timestep
    2402            0 :          s% max_model_number = -1111
    2403            0 :          s% max_years_for_timestep = relax_R_center_dt/secyer
    2404              :          call do_internal_evolve( &
    2405              :                id, before_evolve_relax_R_center, &
    2406              :                relax_R_center_adjust_model, relax_R_center_check_model, &
    2407            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    2408              : 
    2409            0 :          s% max_model_number = max_model_number
    2410            0 :          s% max_years_for_timestep = max_years_for_timestep
    2411            0 :          call error_check('relax R center',ierr)
    2412              :       end subroutine do_relax_R_center
    2413              : 
    2414              : 
    2415            0 :       subroutine before_evolve_relax_R_center(s, id, lipar, ipar, lrpar, rpar, ierr)
    2416              :          type (star_info), pointer :: s
    2417              :          integer, intent(in) :: id, lipar, lrpar
    2418              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2419              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2420              :          integer, intent(out) :: ierr
    2421            0 :          ierr = 0
    2422            0 :          call setup_before_relax(s)
    2423            0 :          s% max_model_number = -111
    2424            0 :          s% dt_next =  rpar(3)  ! relax_R_center_dt
    2425            0 :       end subroutine before_evolve_relax_R_center
    2426              : 
    2427            0 :       integer function relax_R_center_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    2428              :          type (star_info), pointer :: s
    2429              :          integer, intent(in) :: id, lipar, lrpar
    2430              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2431              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2432            0 :          relax_R_center_adjust_model = keep_going
    2433            0 :       end function relax_R_center_adjust_model
    2434              : 
    2435            0 :       integer function relax_R_center_check_model(s, id, lipar, ipar, lrpar, rpar)
    2436              :          use do_one_utils, only:do_bare_bones_check_model
    2437              :          type (star_info), pointer :: s
    2438              :          integer, intent(in) :: id, lipar, lrpar
    2439              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2440              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2441              :          integer :: ierr
    2442              :          real(dp) :: new_R_center, dlgR_per_step, relax_R_center_dt, next
    2443              :          logical, parameter :: dbg = .false.
    2444              : 
    2445              :          include 'formats'
    2446              : 
    2447            0 :          relax_R_center_check_model = do_bare_bones_check_model(id)
    2448            0 :          if (relax_R_center_check_model /= keep_going) return
    2449              : 
    2450            0 :          new_R_center = rpar(1)
    2451            0 :          dlgR_per_step = rpar(2)
    2452            0 :          relax_R_center_dt = rpar(3)
    2453              : 
    2454            0 :          if (mod(s% model_number, s% terminal_interval) == 0 .and. s% R_center > 0d0) &
    2455            0 :             write(*,1) 'relax_R_center target/current', new_R_center/s% R_center
    2456              : 
    2457            0 :          if (abs(s% R_center - new_R_center) < 1d-15) then
    2458            0 :             call do1_relax_R_center(s, new_R_center, ierr)
    2459            0 :             if (ierr /= 0) then
    2460            0 :                write(*,*) 'failed in relax_R_center'
    2461              :             end if
    2462            0 :             relax_R_center_check_model = terminate
    2463            0 :             s% termination_code = t_relax_finished_okay
    2464            0 :             return
    2465              :          end if
    2466              : 
    2467            0 :          if (s% dt < relax_R_center_dt*0.9d0) return  ! give a chance to stabilize
    2468              : 
    2469            0 :          if (new_R_center < s% R_center) then
    2470            0 :             next = exp10(safe_log10(s% R_center) - dlgR_per_step)
    2471            0 :             if (next < new_R_center) next = new_R_center
    2472            0 :          else if (s% R_center < 1) then
    2473            0 :             next = 1
    2474              :          else
    2475            0 :             next = exp10(safe_log10(s% R_center) + dlgR_per_step)
    2476            0 :             if (next > new_R_center) next = new_R_center
    2477              :          end if
    2478              : 
    2479              :          if (dbg) write(*,1) 'next', next
    2480              : 
    2481            0 :          call do1_relax_R_center(s, next, ierr)
    2482            0 :          if (ierr /= 0) then
    2483            0 :             write(*,*) 'failed in relax_R_center'
    2484            0 :             relax_R_center_check_model = terminate
    2485              :          end if
    2486              : 
    2487              :       end function relax_R_center_check_model
    2488              : 
    2489              : 
    2490            0 :       subroutine do1_relax_R_center(s, new_Rcenter, ierr)
    2491              :          ! adjust all lnR's to keep same density for each cell as 1st guess for next model
    2492              :          use star_utils, only: set_qs, store_lnR_in_xh
    2493              :          type (star_info), pointer :: s
    2494              :          real(dp), intent(in) :: new_Rcenter  ! cm
    2495              :          integer, intent(out) :: ierr
    2496              :          real(dp) :: dm, rho, dr3, rp13
    2497              :          integer :: k
    2498              :          include 'formats'
    2499            0 :          ierr = 0
    2500            0 :          s% R_center = new_Rcenter
    2501              :          ! adjust lnR's
    2502            0 :          rp13 = s% R_center*s% R_center*s% R_center
    2503            0 :          do k = s% nz, 1, -1
    2504            0 :             dm = s% dm(k)
    2505            0 :             rho = s% rho(k)
    2506            0 :             dr3 = dm/(rho*four_thirds_pi)  ! dm/rho is cell volume
    2507            0 :             call store_lnR_in_xh(s, k, log(rp13 + dr3)*one_third)
    2508            0 :             rp13 = rp13 + dr3
    2509              :          end do
    2510            0 :       end subroutine do1_relax_R_center
    2511              : 
    2512              : 
    2513            0 :       subroutine do_relax_v_center(id, new_v_center, dv_per_step, relax_v_center_dt, ierr)
    2514              :          integer, intent(in) :: id
    2515              :          real(dp), intent(in) :: new_v_center, dv_per_step, relax_v_center_dt
    2516              :          integer, intent(out) :: ierr
    2517              :          integer, parameter ::  lipar=1, lrpar=3
    2518              :          integer :: max_model_number
    2519              :          real(dp) :: max_years_for_timestep
    2520              :          type (star_info), pointer :: s
    2521              :          integer, target :: ipar_ary(lipar)
    2522              :          integer, pointer :: ipar(:)
    2523              :          real(dp), target :: rpar_ary(lrpar)
    2524              :          real(dp), pointer :: rpar(:)
    2525            0 :          rpar => rpar_ary
    2526            0 :          ipar => ipar_ary
    2527              :          include 'formats'
    2528              :          ierr = 0
    2529            0 :          if (new_v_center < 0) then
    2530            0 :             ierr = -1
    2531            0 :             write(*,*) 'invalid new_v_center', new_v_center
    2532            0 :             return
    2533              :          end if
    2534            0 :          call get_star_ptr(id, s, ierr)
    2535            0 :          if (ierr /= 0) return
    2536            0 :          if (abs(s% v_center - new_v_center) < &
    2537              :                1d-6*max(1d-6,abs(s% v_center),abs(new_v_center))) then
    2538            0 :             s% v_center = new_v_center
    2539            0 :             return
    2540              :          end if
    2541            0 :          write(*,'(A)')
    2542            0 :          write(*,1) 'current v_center', s% v_center
    2543            0 :          write(*,1) 'relax to new_v_center', new_v_center
    2544            0 :          write(*,'(A)')
    2545            0 :          write(*,1) 'dv_per_step', dv_per_step
    2546            0 :          write(*,'(A)')
    2547            0 :          rpar(1) = new_v_center
    2548            0 :          rpar(2) = dv_per_step
    2549            0 :          rpar(3) = relax_v_center_dt
    2550            0 :          max_model_number = s% max_model_number
    2551            0 :          max_years_for_timestep = s% max_years_for_timestep
    2552            0 :          s% max_model_number = -1111
    2553            0 :          s% max_years_for_timestep = relax_v_center_dt/secyer
    2554              :          call do_internal_evolve( &
    2555              :                id, before_evolve_relax_v_center, &
    2556              :                relax_v_center_adjust_model, relax_v_center_check_model, &
    2557            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    2558              : 
    2559            0 :          s% max_model_number = max_model_number
    2560            0 :          s% max_years_for_timestep = max_years_for_timestep
    2561            0 :          call error_check('relax V center',ierr)
    2562              :       end subroutine do_relax_v_center
    2563              : 
    2564              : 
    2565            0 :       subroutine before_evolve_relax_v_center(s, id, lipar, ipar, lrpar, rpar, ierr)
    2566              :          type (star_info), pointer :: s
    2567              :          integer, intent(in) :: id, lipar, lrpar
    2568              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2569              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2570              :          integer, intent(out) :: ierr
    2571            0 :          ierr = 0
    2572            0 :          call setup_before_relax(s)
    2573            0 :          s% max_model_number = -111
    2574            0 :          s% dt_next =  rpar(3)  ! relax_v_center_dt
    2575            0 :       end subroutine before_evolve_relax_v_center
    2576              : 
    2577            0 :       integer function relax_v_center_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    2578              :          type (star_info), pointer :: s
    2579              :          integer, intent(in) :: id, lipar, lrpar
    2580              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2581              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2582            0 :          relax_v_center_adjust_model = keep_going
    2583            0 :       end function relax_v_center_adjust_model
    2584              : 
    2585            0 :       integer function relax_v_center_check_model(s, id, lipar, ipar, lrpar, rpar)
    2586              :          use do_one_utils, only:do_bare_bones_check_model
    2587              :          type (star_info), pointer :: s
    2588              :          integer, intent(in) :: id, lipar, lrpar
    2589              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2590              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2591              :          real(dp) :: new_v_center, dv_per_step, relax_v_center_dt, next
    2592              :          logical, parameter :: dbg = .false.
    2593              : 
    2594              :          include 'formats'
    2595              : 
    2596            0 :          relax_v_center_check_model = do_bare_bones_check_model(id)
    2597            0 :          if (relax_v_center_check_model /= keep_going) return
    2598              : 
    2599            0 :          new_v_center = rpar(1)
    2600            0 :          dv_per_step = rpar(2)
    2601            0 :          relax_v_center_dt = rpar(3)
    2602              : 
    2603            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    2604            0 :             write(*,1) 'target v_center current', new_v_center, s% v_center
    2605              : 
    2606            0 :          if (abs(s% v_center - new_v_center) < &
    2607              :                1d-6*max(1d-6,abs(s% v_center),abs(new_v_center))) then
    2608            0 :             s% v_center = new_v_center
    2609            0 :             relax_v_center_check_model = terminate
    2610            0 :             s% termination_code = t_relax_finished_okay
    2611            0 :             return
    2612              :          end if
    2613              : 
    2614            0 :          if (s% dt < relax_v_center_dt*0.9d0) return  ! give a chance to stabilize
    2615              : 
    2616            0 :          if (new_v_center < s% v_center) then
    2617            0 :             next = s% v_center - dv_per_step
    2618              :             if (next < new_v_center) next = new_v_center
    2619              :          else
    2620            0 :             next = s% v_center + dv_per_step
    2621              :             if (next > new_v_center) next = new_v_center
    2622              :          end if
    2623              : 
    2624              :          if (dbg) write(*,1) 'next', next
    2625              : 
    2626            0 :          s% v_center = next
    2627              : 
    2628            0 :       end function relax_v_center_check_model
    2629              : 
    2630              : 
    2631            0 :       subroutine do_relax_L_center(id, new_L_center, dlgL_per_step, relax_L_center_dt, ierr)
    2632              :          integer, intent(in) :: id
    2633              :          real(dp), intent(in) :: new_L_center, dlgL_per_step, relax_L_center_dt
    2634              :          integer, intent(out) :: ierr
    2635              :          integer, parameter ::  lipar=1, lrpar=3
    2636              :          integer :: max_model_number
    2637              :          real(dp) :: max_years_for_timestep
    2638              :          type (star_info), pointer :: s
    2639              :          integer, target :: ipar_ary(lipar)
    2640              :          integer, pointer :: ipar(:)
    2641              :          real(dp), target :: rpar_ary(lrpar)
    2642              :          real(dp), pointer :: rpar(:)
    2643            0 :          rpar => rpar_ary
    2644            0 :          ipar => ipar_ary
    2645              :          include 'formats'
    2646              :          ierr = 0
    2647            0 :          call get_star_ptr(id, s, ierr)
    2648            0 :          if (ierr /= 0) return
    2649            0 :          if (abs(new_L_center - s% L_center) <= &
    2650              :                1d-10*max(abs(new_L_center),abs(s% L_center),1d0)) then
    2651            0 :             s% L_center = new_L_center
    2652            0 :             return
    2653              :          end if
    2654            0 :          write(*,'(A)')
    2655            0 :          write(*,1) 'current L_center', s% L_center
    2656            0 :          write(*,1) 'relax to new_L_center', new_L_center
    2657            0 :          write(*,'(A)')
    2658            0 :          write(*,1) 'dlgL_per_step', dlgL_per_step
    2659            0 :          write(*,'(A)')
    2660            0 :          rpar(1) = new_L_center
    2661            0 :          rpar(2) = dlgL_per_step*(new_L_center - s% L_center)
    2662            0 :          rpar(3) = relax_L_center_dt
    2663            0 :          max_model_number = s% max_model_number
    2664            0 :          max_years_for_timestep = s% max_years_for_timestep
    2665            0 :          s% max_model_number = -1111
    2666            0 :          s% max_years_for_timestep = relax_L_center_dt/secyer
    2667              :          call do_internal_evolve( &
    2668              :                id, before_evolve_relax_L_center, &
    2669              :                relax_L_center_adjust_model, relax_L_center_check_model, &
    2670            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    2671              : 
    2672            0 :          s% max_model_number = max_model_number
    2673            0 :          s% max_years_for_timestep = max_years_for_timestep
    2674            0 :          call error_check('relax L center',ierr)
    2675              :       end subroutine do_relax_L_center
    2676              : 
    2677              : 
    2678            0 :       subroutine before_evolve_relax_L_center(s, id, lipar, ipar, lrpar, rpar, ierr)
    2679              :          type (star_info), pointer :: s
    2680              :          integer, intent(in) :: id, lipar, lrpar
    2681              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2682              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2683              :          integer, intent(out) :: ierr
    2684            0 :          ierr = 0
    2685            0 :          call setup_before_relax(s)
    2686            0 :          s% max_model_number = -111
    2687            0 :          s% dt_next =  rpar(3)  ! relax_L_center_dt
    2688            0 :       end subroutine before_evolve_relax_L_center
    2689              : 
    2690            0 :       integer function relax_L_center_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    2691              :          type (star_info), pointer :: s
    2692              :          integer, intent(in) :: id, lipar, lrpar
    2693              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2694              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2695            0 :          relax_L_center_adjust_model = keep_going
    2696            0 :       end function relax_L_center_adjust_model
    2697              : 
    2698            0 :       integer function relax_L_center_check_model(s, id, lipar, ipar, lrpar, rpar)
    2699              :          use do_one_utils, only:do_bare_bones_check_model
    2700              :          type (star_info), pointer :: s
    2701              :          integer, intent(in) :: id, lipar, lrpar
    2702              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2703              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2704              :          integer :: ierr
    2705              :          real(dp) :: new_L_center, dL, relax_L_center_dt, next
    2706              :          logical, parameter :: dbg = .false.
    2707              : 
    2708              :          include 'formats'
    2709              : 
    2710            0 :          relax_L_center_check_model = do_bare_bones_check_model(id)
    2711            0 :          if (relax_L_center_check_model /= keep_going) return
    2712              : 
    2713            0 :          new_L_center = rpar(1)
    2714            0 :          dL = rpar(2)
    2715            0 :          relax_L_center_dt = rpar(3)
    2716              : 
    2717              : 
    2718            0 :          if (mod(s% model_number, s% terminal_interval) == 0 .and. s% L_center>0.d0) &
    2719            0 :             write(*,1) 'relax_L_center target/current', new_L_center/s% L_center
    2720              : 
    2721            0 :          if (abs(new_L_center - s% L_center) < abs(dL)) then
    2722            0 :             call do1_relax_L_center(s, new_L_center, ierr)
    2723            0 :             if (ierr /= 0) then
    2724            0 :                write(*,*) 'failed in relax_L_center'
    2725              :             end if
    2726            0 :             relax_L_center_check_model = terminate
    2727            0 :             s% termination_code = t_relax_finished_okay
    2728            0 :             return
    2729              :          end if
    2730              : 
    2731            0 :          if (s% dt < relax_L_center_dt*0.9d0) return  ! give a chance to stabilize
    2732              : 
    2733            0 :          next = s% L_center + dL
    2734              :          if (dbg) write(*,1) 'next', next
    2735              : 
    2736            0 :          call do1_relax_L_center(s, next, ierr)
    2737            0 :          if (ierr /= 0) then
    2738            0 :             write(*,*) 'failed in relax_L_center'
    2739            0 :             relax_L_center_check_model = terminate
    2740              :          end if
    2741              : 
    2742              :       end function relax_L_center_check_model
    2743              : 
    2744              : 
    2745            0 :       subroutine do1_relax_L_center(s, new_Lcenter, ierr)
    2746              :          type (star_info), pointer :: s
    2747              :          real(dp), intent(in) :: new_Lcenter
    2748              :          integer, intent(out) :: ierr
    2749              :          real(dp) :: L_center_prev, dL
    2750              :          integer :: i_lum, nz, k
    2751              :          include 'formats'
    2752            0 :          ierr = 0
    2753            0 :          nz = s% nz
    2754            0 :          L_center_prev = s% L_center
    2755            0 :          s% L_center = new_Lcenter
    2756            0 :          i_lum = s% i_lum
    2757            0 :          if (i_lum == 0) return
    2758            0 :          dL = new_Lcenter - L_center_prev
    2759            0 :          do k=1,nz
    2760            0 :             s% xh(i_lum,k) = s% xh(i_lum,k) + dL
    2761              :          end do
    2762              :       end subroutine do1_relax_L_center
    2763              : 
    2764              : 
    2765            0 :       subroutine do_relax_dxdt_nuc_factor(id, new_value, per_step_multiplier, ierr)
    2766              :          integer, intent(in) :: id
    2767              :          real(dp), intent(in) :: new_value, per_step_multiplier
    2768              :          integer, intent(out) :: ierr
    2769              :          integer, parameter ::  lipar=1, lrpar=2
    2770              :          integer :: max_model_number
    2771              :          type (star_info), pointer :: s
    2772              :          integer, target :: ipar_ary(lipar)
    2773              :          integer, pointer :: ipar(:)
    2774              :          real(dp), target :: rpar_ary(lrpar)
    2775              :          real(dp), pointer :: rpar(:)
    2776            0 :          rpar => rpar_ary
    2777            0 :          ipar => ipar_ary
    2778              :          include 'formats'
    2779              :          ierr = 0
    2780            0 :          if (new_value <= 0) then
    2781            0 :             ierr = -1
    2782            0 :             write(*,*) 'invalid new_value', new_value
    2783            0 :             return
    2784              :          end if
    2785            0 :          if (per_step_multiplier <= 0 .or. per_step_multiplier == 1) then
    2786            0 :             ierr = -1
    2787            0 :             write(*,*) 'invalid per_step_multiplier', per_step_multiplier
    2788            0 :             return
    2789              :          end if
    2790            0 :          call get_star_ptr(id, s, ierr)
    2791            0 :          if (ierr /= 0) return
    2792            0 :          if (abs(new_value - s% dxdt_nuc_factor) <= 1d-6) then
    2793            0 :             s% dxdt_nuc_factor = new_value
    2794            0 :             return
    2795              :          end if
    2796            0 :          write(*,'(A)')
    2797            0 :          write(*,1) 'current dxdt_nuc_factor', s% dxdt_nuc_factor
    2798            0 :          write(*,1) 'relax to new_value', new_value
    2799            0 :          write(*,'(A)')
    2800            0 :          write(*,1) 'per_step_multiplier', per_step_multiplier
    2801            0 :          write(*,'(A)')
    2802            0 :          rpar(1) = new_value
    2803            0 :          rpar(2) = per_step_multiplier
    2804            0 :          max_model_number = s% max_model_number
    2805            0 :          s% max_model_number = -1111
    2806              :          call do_internal_evolve( &
    2807              :                id, before_evolve_relax_dxdt_nuc_factor, &
    2808              :                relax_dxdt_nuc_factor_adjust_model, relax_dxdt_nuc_factor_check_model, &
    2809            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    2810            0 :          s% max_model_number = max_model_number
    2811            0 :          s% dxdt_nuc_factor = new_value
    2812            0 :          call error_check('relax dxdt nuc factor',ierr)
    2813              :       end subroutine do_relax_dxdt_nuc_factor
    2814              : 
    2815              : 
    2816            0 :       subroutine before_evolve_relax_dxdt_nuc_factor(s, id, lipar, ipar, lrpar, rpar, ierr)
    2817              :          type (star_info), pointer :: s
    2818              :          integer, intent(in) :: id, lipar, lrpar
    2819              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2820              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2821              :          integer, intent(out) :: ierr
    2822            0 :          ierr = 0
    2823            0 :          call turn_off_winds(s)
    2824            0 :          s% max_model_number = -111
    2825            0 :          s% dt_next = secyer*1d-3
    2826            0 :       end subroutine before_evolve_relax_dxdt_nuc_factor
    2827              : 
    2828            0 :       integer function relax_dxdt_nuc_factor_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    2829              :          type (star_info), pointer :: s
    2830              :          integer, intent(in) :: id, lipar, lrpar
    2831              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2832              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2833            0 :          relax_dxdt_nuc_factor_adjust_model = keep_going
    2834            0 :       end function relax_dxdt_nuc_factor_adjust_model
    2835              : 
    2836            0 :       integer function relax_dxdt_nuc_factor_check_model(s, id, lipar, ipar, lrpar, rpar)
    2837              :          use do_one_utils, only:do_bare_bones_check_model
    2838              :          type (star_info), pointer :: s
    2839              :          integer, intent(in) :: id, lipar, lrpar
    2840              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2841              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2842              :          real(dp) :: new_value, per_step_multiplier
    2843              :          logical, parameter :: dbg = .false.
    2844              : 
    2845              :          include 'formats'
    2846              : 
    2847            0 :          relax_dxdt_nuc_factor_check_model = do_bare_bones_check_model(id)
    2848            0 :          if (relax_dxdt_nuc_factor_check_model /= keep_going) return
    2849              : 
    2850            0 :          new_value = rpar(1)
    2851            0 :          per_step_multiplier = rpar(2)
    2852              : 
    2853            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    2854            0 :             write(*,1) 'new_value current', new_value, s% dxdt_nuc_factor
    2855              : 
    2856            0 :          s% dxdt_nuc_factor = s% dxdt_nuc_factor * per_step_multiplier
    2857              : 
    2858            0 :          if ((per_step_multiplier < 1 .and. s% dxdt_nuc_factor < new_value) .or. &
    2859              :              (per_step_multiplier > 1 .and. s% dxdt_nuc_factor > new_value)) then
    2860            0 :             s% dxdt_nuc_factor = new_value
    2861            0 :             relax_dxdt_nuc_factor_check_model = terminate
    2862            0 :             s% termination_code = t_relax_finished_okay
    2863            0 :             return
    2864              :          end if
    2865              : 
    2866              :       end function relax_dxdt_nuc_factor_check_model
    2867              : 
    2868              : 
    2869            0 :       subroutine do_relax_eps_nuc_factor(id, new_value, per_step_multiplier, ierr)
    2870              :          integer, intent(in) :: id
    2871              :          real(dp), intent(in) :: new_value, per_step_multiplier
    2872              :          integer, intent(out) :: ierr
    2873              :          integer, parameter ::  lipar=1, lrpar=2
    2874              :          integer :: max_model_number
    2875              :          type (star_info), pointer :: s
    2876              :          integer, target :: ipar_ary(lipar)
    2877              :          integer, pointer :: ipar(:)
    2878              :          real(dp), target :: rpar_ary(lrpar)
    2879              :          real(dp), pointer :: rpar(:)
    2880            0 :          rpar => rpar_ary
    2881            0 :          ipar => ipar_ary
    2882              :          include 'formats'
    2883              :          ierr = 0
    2884            0 :          if (new_value <= 0) then
    2885            0 :             ierr = -1
    2886            0 :             write(*,*) 'invalid new_value', new_value
    2887            0 :             return
    2888              :          end if
    2889            0 :          if (per_step_multiplier <= 0 .or. per_step_multiplier == 1) then
    2890            0 :             ierr = -1
    2891            0 :             write(*,*) 'invalid per_step_multiplier', per_step_multiplier
    2892            0 :             return
    2893              :          end if
    2894            0 :          call get_star_ptr(id, s, ierr)
    2895            0 :          if (ierr /= 0) return
    2896            0 :          if (abs(new_value - s% eps_nuc_factor) <= 1d-6) then
    2897            0 :             s% eps_nuc_factor = new_value
    2898            0 :             return
    2899              :          end if
    2900            0 :          write(*,'(A)')
    2901            0 :          write(*,1) 'current eps_nuc_factor', s% eps_nuc_factor
    2902            0 :          write(*,1) 'relax to new_value', new_value
    2903            0 :          write(*,'(A)')
    2904            0 :          write(*,1) 'per_step_multiplier', per_step_multiplier
    2905            0 :          write(*,'(A)')
    2906            0 :          rpar(1) = new_value
    2907            0 :          rpar(2) = per_step_multiplier
    2908            0 :          max_model_number = s% max_model_number
    2909            0 :          s% max_model_number = -1111
    2910              :          call do_internal_evolve( &
    2911              :                id, before_evolve_relax_eps_nuc_factor, &
    2912              :                relax_eps_nuc_factor_adjust_model, relax_eps_nuc_factor_check_model, &
    2913            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    2914            0 :          s% max_model_number = max_model_number
    2915            0 :          s% eps_nuc_factor = new_value
    2916            0 :          call error_check('relax eps nuc factor',ierr)
    2917              :       end subroutine do_relax_eps_nuc_factor
    2918              : 
    2919              : 
    2920            0 :       subroutine before_evolve_relax_eps_nuc_factor(s, id, lipar, ipar, lrpar, rpar, ierr)
    2921              :          type (star_info), pointer :: s
    2922              :          integer, intent(in) :: id, lipar, lrpar
    2923              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2924              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2925              :          integer, intent(out) :: ierr
    2926            0 :          ierr = 0
    2927            0 :          call turn_off_winds(s)
    2928            0 :          s% max_model_number = -111
    2929            0 :          s% dt_next = secyer*1d-3
    2930            0 :       end subroutine before_evolve_relax_eps_nuc_factor
    2931              : 
    2932            0 :       integer function relax_eps_nuc_factor_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    2933              :          type (star_info), pointer :: s
    2934              :          integer, intent(in) :: id, lipar, lrpar
    2935              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2936              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2937            0 :          relax_eps_nuc_factor_adjust_model = keep_going
    2938            0 :       end function relax_eps_nuc_factor_adjust_model
    2939              : 
    2940            0 :       integer function relax_eps_nuc_factor_check_model(s, id, lipar, ipar, lrpar, rpar)
    2941              :          use do_one_utils, only:do_bare_bones_check_model
    2942              :          type (star_info), pointer :: s
    2943              :          integer, intent(in) :: id, lipar, lrpar
    2944              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    2945              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    2946              :          real(dp) :: new_value, per_step_multiplier
    2947              :          logical, parameter :: dbg = .false.
    2948              : 
    2949              :          include 'formats'
    2950              : 
    2951            0 :          relax_eps_nuc_factor_check_model = do_bare_bones_check_model(id)
    2952            0 :          if (relax_eps_nuc_factor_check_model /= keep_going) return
    2953              : 
    2954            0 :          new_value = rpar(1)
    2955            0 :          per_step_multiplier = rpar(2)
    2956              : 
    2957            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    2958            0 :             write(*,1) 'new_value, current', new_value, s% eps_nuc_factor
    2959              : 
    2960            0 :          s% eps_nuc_factor = s% eps_nuc_factor * per_step_multiplier
    2961              : 
    2962            0 :          if ((per_step_multiplier < 1 .and. s% eps_nuc_factor < new_value) .or. &
    2963              :              (per_step_multiplier > 1 .and. s% eps_nuc_factor > new_value)) then
    2964            0 :             s% eps_nuc_factor = new_value
    2965            0 :             relax_eps_nuc_factor_check_model = terminate
    2966            0 :             s% termination_code = t_relax_finished_okay
    2967            0 :             return
    2968              :          end if
    2969              : 
    2970              :       end function relax_eps_nuc_factor_check_model
    2971              : 
    2972              : 
    2973            0 :       subroutine do_relax_opacity_max(id, new_value, per_step_multiplier, ierr)
    2974              :          integer, intent(in) :: id
    2975              :          real(dp), intent(in) :: new_value, per_step_multiplier
    2976              :          integer, intent(out) :: ierr
    2977              :          integer, parameter ::  lipar=1, lrpar=2
    2978              :          integer :: max_model_number
    2979              :          type (star_info), pointer :: s
    2980              :          integer, target :: ipar_ary(lipar)
    2981              :          integer, pointer :: ipar(:)
    2982              :          real(dp), target :: rpar_ary(lrpar)
    2983              :          real(dp), pointer :: rpar(:)
    2984            0 :          rpar => rpar_ary
    2985            0 :          ipar => ipar_ary
    2986              :          include 'formats'
    2987              :          ierr = 0
    2988            0 :          if (new_value <= 0) then
    2989            0 :             ierr = -1
    2990            0 :             write(*,*) 'invalid new_value', new_value
    2991            0 :             return
    2992              :          end if
    2993            0 :          if (per_step_multiplier <= 0 .or. per_step_multiplier == 1) then
    2994            0 :             ierr = -1
    2995            0 :             write(*,*) 'invalid per_step_multiplier', per_step_multiplier
    2996            0 :             return
    2997              :          end if
    2998            0 :          call get_star_ptr(id, s, ierr)
    2999            0 :          if (ierr /= 0) return
    3000            0 :          if (s% opacity_max <= 0) then
    3001            0 :             ierr = -1
    3002            0 :             write(*,*) 'invalid opacity_max', s% opacity_max
    3003            0 :             return
    3004              :          end if
    3005            0 :          if (abs(new_value - s% opacity_max) <= 1d-6) then
    3006            0 :             s% opacity_max = new_value
    3007            0 :             return
    3008              :          end if
    3009            0 :          write(*,'(A)')
    3010            0 :          write(*,1) 'current opacity_max', s% opacity_max
    3011            0 :          write(*,1) 'relax to new_value', new_value
    3012            0 :          write(*,'(A)')
    3013            0 :          write(*,1) 'per_step_multiplier', per_step_multiplier
    3014            0 :          write(*,'(A)')
    3015            0 :          rpar(1) = new_value
    3016            0 :          rpar(2) = per_step_multiplier
    3017            0 :          max_model_number = s% max_model_number
    3018            0 :          s% max_model_number = -1111
    3019              :          call do_internal_evolve( &
    3020              :                id, before_evolve_relax_opacity_max, &
    3021              :                relax_opacity_max_adjust_model, relax_opacity_max_check_model, &
    3022            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    3023              : 
    3024            0 :          s% max_model_number = max_model_number
    3025            0 :          s% opacity_max = new_value
    3026            0 :          s% dt_next = rpar(1)  ! keep dt from relax
    3027            0 :          call error_check('relax opacity max',ierr)
    3028              :       end subroutine do_relax_opacity_max
    3029              : 
    3030              : 
    3031            0 :       subroutine before_evolve_relax_opacity_max(s, id, lipar, ipar, lrpar, rpar, ierr)
    3032              :          type (star_info), pointer :: s
    3033              :          integer, intent(in) :: id, lipar, lrpar
    3034              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3035              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3036              :          integer, intent(out) :: ierr
    3037            0 :          ierr = 0
    3038            0 :          s% max_model_number = -111
    3039            0 :          s% dt_next = secyer*1d-3
    3040            0 :          call turn_off_winds(s)
    3041            0 :       end subroutine before_evolve_relax_opacity_max
    3042              : 
    3043            0 :       integer function relax_opacity_max_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    3044              :          type (star_info), pointer :: s
    3045              :          integer, intent(in) :: id, lipar, lrpar
    3046              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3047              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3048            0 :          relax_opacity_max_adjust_model = keep_going
    3049            0 :       end function relax_opacity_max_adjust_model
    3050              : 
    3051            0 :       integer function relax_opacity_max_check_model(s, id, lipar, ipar, lrpar, rpar)
    3052              :          use do_one_utils, only:do_bare_bones_check_model
    3053              :          type (star_info), pointer :: s
    3054              :          integer, intent(in) :: id, lipar, lrpar
    3055              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3056              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3057              :          real(dp) :: new_value, per_step_multiplier
    3058              :          logical, parameter :: dbg = .false.
    3059              : 
    3060              :          include 'formats'
    3061              : 
    3062            0 :          relax_opacity_max_check_model = do_bare_bones_check_model(id)
    3063            0 :          if (relax_opacity_max_check_model /= keep_going) return
    3064              : 
    3065            0 :          new_value = rpar(1)
    3066            0 :          per_step_multiplier = rpar(2)
    3067              : 
    3068            0 :          s% opacity_max = s% opacity_max * per_step_multiplier
    3069              : 
    3070            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    3071            0 :             write(*,1) 'relax opacity', s% opacity_max, new_value
    3072              : 
    3073            0 :          if ((per_step_multiplier < 1 .and. s% opacity_max < new_value) .or. &
    3074              :              (per_step_multiplier > 1 .and. s% opacity_max > new_value)) then
    3075            0 :             s% opacity_max = new_value
    3076            0 :             relax_opacity_max_check_model = terminate
    3077            0 :             s% termination_code = t_relax_finished_okay
    3078            0 :             rpar(1) = s% dt
    3079            0 :             return
    3080              :          end if
    3081              : 
    3082              :       end function relax_opacity_max_check_model
    3083              : 
    3084              : 
    3085            0 :       subroutine do_relax_max_surf_dq(id, new_value, per_step_multiplier, ierr)
    3086              :          integer, intent(in) :: id
    3087              :          real(dp), intent(in) :: new_value, per_step_multiplier
    3088              :          integer, intent(out) :: ierr
    3089              :          integer, parameter ::  lipar=1, lrpar=2
    3090              :          integer :: max_model_number
    3091              :          type (star_info), pointer :: s
    3092              :          integer, target :: ipar_ary(lipar)
    3093              :          integer, pointer :: ipar(:)
    3094              :          real(dp), target :: rpar_ary(lrpar)
    3095              :          real(dp), pointer :: rpar(:)
    3096            0 :          rpar => rpar_ary
    3097            0 :          ipar => ipar_ary
    3098              :          include 'formats'
    3099              :          ierr = 0
    3100            0 :          if (new_value <= 0) then
    3101            0 :             ierr = -1
    3102            0 :             write(*,*) 'invalid new_value', new_value
    3103            0 :             return
    3104              :          end if
    3105            0 :          if (per_step_multiplier <= 0 .or. per_step_multiplier == 1) then
    3106            0 :             ierr = -1
    3107            0 :             write(*,*) 'invalid per_step_multiplier', per_step_multiplier
    3108            0 :             return
    3109              :          end if
    3110            0 :          call get_star_ptr(id, s, ierr)
    3111            0 :          if (ierr /= 0) return
    3112            0 :          if (s% max_surface_cell_dq <= 0) then
    3113            0 :             ierr = -1
    3114            0 :             write(*,*) 'invalid max_surf_dq', s% max_surface_cell_dq
    3115            0 :             return
    3116              :          end if
    3117            0 :          if (abs(new_value - s% max_surface_cell_dq) <= &
    3118              :                1d-6*min(new_value,s% max_surface_cell_dq)) then
    3119            0 :             s% max_surface_cell_dq = new_value
    3120            0 :             return
    3121              :          end if
    3122            0 :          write(*,'(A)')
    3123            0 :          write(*,1) 'current max_surf_dq', s% max_surface_cell_dq
    3124            0 :          write(*,1) 'relax to new_value', new_value
    3125            0 :          write(*,'(A)')
    3126            0 :          write(*,1) 'per_step_multiplier', per_step_multiplier
    3127            0 :          write(*,'(A)')
    3128            0 :          rpar(1) = new_value
    3129            0 :          rpar(2) = per_step_multiplier
    3130            0 :          max_model_number = s% max_model_number
    3131            0 :          s% max_model_number = -1111
    3132              :          call do_internal_evolve( &
    3133              :                id, before_evolve_relax_max_surf_dq, &
    3134              :                relax_max_surf_dq_adjust_model, relax_max_surf_dq_check_model, &
    3135            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    3136            0 :          s% max_model_number = max_model_number
    3137            0 :          s% max_surface_cell_dq = new_value
    3138            0 :          s% dt_next = rpar(1)  ! keep dt from relax
    3139            0 :          call error_check('relax max surf dq',ierr)
    3140              :       end subroutine do_relax_max_surf_dq
    3141              : 
    3142              : 
    3143            0 :       subroutine before_evolve_relax_max_surf_dq(s, id, lipar, ipar, lrpar, rpar, ierr)
    3144              :          type (star_info), pointer :: s
    3145              :          integer, intent(in) :: id, lipar, lrpar
    3146              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3147              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3148              :          integer, intent(out) :: ierr
    3149            0 :          ierr = 0
    3150            0 :          s% max_model_number = -111
    3151            0 :          s% dt_next = secyer*1d-3
    3152            0 :          call turn_off_winds(s)
    3153            0 :       end subroutine before_evolve_relax_max_surf_dq
    3154              : 
    3155            0 :       integer function relax_max_surf_dq_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    3156              :          type (star_info), pointer :: s
    3157              :          integer, intent(in) :: id, lipar, lrpar
    3158              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3159              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3160            0 :          relax_max_surf_dq_adjust_model = keep_going
    3161            0 :       end function relax_max_surf_dq_adjust_model
    3162              : 
    3163            0 :       integer function relax_max_surf_dq_check_model(s, id, lipar, ipar, lrpar, rpar)
    3164              :          use do_one_utils, only:do_bare_bones_check_model
    3165              :          type (star_info), pointer :: s
    3166              :          integer, intent(in) :: id, lipar, lrpar
    3167              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3168              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3169              :          real(dp) :: new_value, per_step_multiplier
    3170              :          logical, parameter :: dbg = .false.
    3171              : 
    3172              :          include 'formats'
    3173              : 
    3174            0 :          relax_max_surf_dq_check_model = do_bare_bones_check_model(id)
    3175            0 :          if (relax_max_surf_dq_check_model /= keep_going) return
    3176              : 
    3177            0 :          new_value = rpar(1)
    3178            0 :          per_step_multiplier = rpar(2)
    3179              : 
    3180            0 :          s% max_surface_cell_dq = s% max_surface_cell_dq * per_step_multiplier
    3181              : 
    3182            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    3183            0 :            write(*,1) 'relax max_surface_cell_dq', s% max_surface_cell_dq, new_value
    3184              : 
    3185            0 :          if ((per_step_multiplier < 1 .and. s% max_surface_cell_dq < new_value) .or. &
    3186              :              (per_step_multiplier > 1 .and. s% max_surface_cell_dq > new_value)) then
    3187            0 :             s% max_surface_cell_dq = new_value
    3188            0 :             relax_max_surf_dq_check_model = terminate
    3189            0 :             s% termination_code = t_relax_finished_okay
    3190            0 :             rpar(1) = s% dt
    3191            0 :             return
    3192              :          end if
    3193              : 
    3194              :       end function relax_max_surf_dq_check_model
    3195              : 
    3196              : 
    3197            0 :       subroutine do_relax_num_steps(id, num_steps, max_timestep, ierr)
    3198              :          integer, intent(in) :: id, num_steps
    3199              :          real(dp), intent(in) :: max_timestep
    3200              :          integer, intent(out) :: ierr
    3201              :          integer, parameter ::  lipar=1, lrpar=1
    3202              :          integer :: max_model_number, model_number
    3203              :          real(dp) :: save_max_timestep, save_max_years_for_timestep
    3204              :          logical :: save_use_gradT
    3205              :          type (star_info), pointer :: s
    3206              :          integer, target :: ipar_ary(lipar)
    3207              :          integer, pointer :: ipar(:)
    3208              :          real(dp), target :: rpar_ary(lrpar)
    3209              :          real(dp), pointer :: rpar(:)
    3210            0 :          rpar => rpar_ary
    3211            0 :          ipar => ipar_ary
    3212              : 
    3213              :          include 'formats'
    3214            0 :          ierr = 0
    3215            0 :          if (num_steps <= 0) return
    3216              : 
    3217              : 
    3218            0 :          call get_star_ptr(id, s, ierr)
    3219            0 :          if (ierr /= 0) return
    3220              : 
    3221            0 :          write(*,'(A)')
    3222            0 :          write(*,2) 'relax_num_steps', num_steps
    3223            0 :          write(*,'(A)')
    3224            0 :          ipar(1) = num_steps
    3225            0 :          if (max_timestep <= 0) then
    3226            0 :             rpar(1) = secyer
    3227              :          else
    3228            0 :             rpar(1) = max_timestep
    3229              :          end if
    3230            0 :          max_model_number = s% max_model_number
    3231            0 :          model_number = s% model_number
    3232            0 :          save_max_timestep = s% max_timestep
    3233            0 :          save_max_years_for_timestep = s% max_years_for_timestep
    3234            0 :          save_use_gradT = s% use_gradT_actual_vs_gradT_MLT_for_T_gradient_eqn
    3235            0 :          s% use_gradT_actual_vs_gradT_MLT_for_T_gradient_eqn = .false.
    3236            0 :          s% model_number = 0
    3237              :          call do_internal_evolve( &
    3238              :                id, before_evolve_relax_num_steps, &
    3239              :                relax_num_steps_adjust_model, relax_num_steps_check_model, &
    3240            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    3241            0 :          s% max_model_number = max_model_number
    3242            0 :          s% model_number = model_number
    3243            0 :          s% max_timestep = save_max_timestep
    3244            0 :          s% max_years_for_timestep = save_max_years_for_timestep
    3245            0 :          s% use_gradT_actual_vs_gradT_MLT_for_T_gradient_eqn = save_use_gradT
    3246            0 :          call error_check('relax num steps',ierr)
    3247              : 
    3248              :       end subroutine do_relax_num_steps
    3249              : 
    3250              : 
    3251            0 :       subroutine before_evolve_relax_num_steps(s, id, lipar, ipar, lrpar, rpar, ierr)
    3252              :          type (star_info), pointer :: s
    3253              :          integer, intent(in) :: id, lipar, lrpar
    3254              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3255              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3256              :          integer, intent(out) :: ierr
    3257            0 :          ierr = 0
    3258            0 :          call setup_before_relax(s)
    3259            0 :          s% max_timestep = rpar(1)
    3260            0 :          s% max_years_for_timestep = s% max_timestep/secyer
    3261            0 :          s% dt_next = s% max_timestep
    3262            0 :          s% max_model_number = ipar(1)
    3263            0 :       end subroutine before_evolve_relax_num_steps
    3264              : 
    3265            0 :       integer function relax_num_steps_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    3266              :          type (star_info), pointer :: s
    3267              :          integer, intent(in) :: id, lipar, lrpar
    3268              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3269              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3270            0 :          relax_num_steps_adjust_model = keep_going
    3271            0 :       end function relax_num_steps_adjust_model
    3272              : 
    3273            0 :       integer function relax_num_steps_check_model(s, id, lipar, ipar, lrpar, rpar)
    3274              :          use do_one_utils, only:do_bare_bones_check_model
    3275              : 
    3276              :          type (star_info), pointer :: s
    3277              :          integer, intent(in) :: id, lipar, lrpar
    3278              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3279              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3280              : 
    3281              :          logical, parameter :: dbg = .false.
    3282              : 
    3283              :          include 'formats'
    3284              : 
    3285            0 :          relax_num_steps_check_model = do_bare_bones_check_model(id)
    3286            0 :          if (relax_num_steps_check_model /= keep_going) return
    3287            0 :          if (s% model_number >= ipar(1)) then
    3288            0 :             relax_num_steps_check_model = terminate
    3289            0 :             s% termination_code = t_relax_finished_okay
    3290              :          end if
    3291              : 
    3292              :       end function relax_num_steps_check_model
    3293              : 
    3294              : 
    3295            0 :       subroutine do_relax_to_radiative_core(id, ierr)
    3296              :          integer, intent(in) :: id
    3297              :          integer, intent(out) :: ierr
    3298              :          integer, parameter ::  lipar=1, lrpar=2
    3299              :          integer :: max_model_number, model_number
    3300              :          real(dp) :: save_max_timestep, save_max_years_for_timestep
    3301              :          type (star_info), pointer :: s
    3302              :          integer, target :: ipar_ary(lipar)
    3303              :          integer, pointer :: ipar(:)
    3304              :          real(dp), target :: rpar_ary(lrpar)
    3305              :          real(dp), pointer :: rpar(:)
    3306              :          real(dp) :: max_timestep
    3307            0 :          rpar => rpar_ary
    3308            0 :          ipar => ipar_ary
    3309              : 
    3310              :          include 'formats'
    3311              :          ierr = 0
    3312              : 
    3313            0 :          call get_star_ptr(id, s, ierr)
    3314            0 :          if (ierr /= 0) return
    3315              : 
    3316            0 :          if (s% star_mass < s% job% pre_ms_check_radiative_core_min_mass) then
    3317            0 :             write(*,*) 'stop relax to begin radiative core because star_mass < pre_ms_check_radiative_core_min_mass'
    3318            0 :             return
    3319              :          end if
    3320              : 
    3321            0 :          max_timestep = 1d3*secyer  ! can provide a parameter for this if necessary
    3322              : 
    3323            0 :          write(*,'(A)')
    3324            0 :          write(*,1) 'relax_to_radiative_core'
    3325            0 :          write(*,'(A)')
    3326              :          if (max_timestep <= 0) then
    3327              :             rpar(1) = secyer
    3328              :          else
    3329            0 :             rpar(1) = max_timestep
    3330              :          end if
    3331            0 :          rpar(2) = 1d99  ! min_conv_mx1_bot
    3332            0 :          max_model_number = s% max_model_number
    3333            0 :          model_number = s% model_number
    3334            0 :          save_max_timestep = s% max_timestep
    3335            0 :          save_max_years_for_timestep = s% max_years_for_timestep
    3336            0 :          s% model_number = 0
    3337              :          call do_internal_evolve( &
    3338              :                id, before_evolve_relax_to_radiative_core, &
    3339              :                relax_to_radiative_core_adjust_model, relax_to_radiative_core_check_model, &
    3340            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    3341            0 :          s% max_model_number = max_model_number
    3342            0 :          s% model_number = model_number
    3343            0 :          s% max_timestep = save_max_timestep
    3344            0 :          s% max_years_for_timestep = save_max_years_for_timestep
    3345            0 :          call error_check('relax_to_radiative_core',ierr)
    3346              : 
    3347              :       end subroutine do_relax_to_radiative_core
    3348              : 
    3349            0 :       subroutine before_evolve_relax_to_radiative_core(s, id, lipar, ipar, lrpar, rpar, ierr)
    3350              :          type (star_info), pointer :: s
    3351              :          integer, intent(in) :: id, lipar, lrpar
    3352              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3353              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3354              :          integer, intent(out) :: ierr
    3355            0 :          ierr = 0
    3356            0 :          call setup_before_relax(s)
    3357              :          !s% max_timestep = rpar(1)
    3358              :          !s% max_years_for_timestep = s% max_timestep/secyer
    3359              :          !s% dt_next = s% max_timestep
    3360            0 :       end subroutine before_evolve_relax_to_radiative_core
    3361              : 
    3362            0 :       integer function relax_to_radiative_core_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    3363              :          type (star_info), pointer :: s
    3364              :          integer, intent(in) :: id, lipar, lrpar
    3365              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3366              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3367            0 :          relax_to_radiative_core_adjust_model = keep_going
    3368            0 :       end function relax_to_radiative_core_adjust_model
    3369              : 
    3370            0 :       integer function relax_to_radiative_core_check_model(s, id, lipar, ipar, lrpar, rpar)
    3371              :          use do_one_utils, only:do_bare_bones_check_model
    3372              :          use report, only: set_power_info
    3373              :          type (star_info), pointer :: s
    3374              :          integer, intent(in) :: id, lipar, lrpar
    3375              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3376              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3377              :          logical, parameter :: dbg = .false.
    3378              :          integer :: ierr
    3379              :          real(dp) :: min_conv_mx1_bot
    3380              :          include 'formats'
    3381            0 :          relax_to_radiative_core_check_model = do_bare_bones_check_model(id)
    3382            0 :          if (relax_to_radiative_core_check_model /= keep_going) return
    3383            0 :          ierr = 0
    3384            0 :          call set_power_info(s)
    3385            0 :          if (s% L_nuc_burn_total/s% L_phot > s% job% pre_ms_check_radiative_core_Lnuc_div_L_limit) then
    3386            0 :             write(*,*) 'reached pre_ms_check_radiative_core_Lnuc_div_L_limit in relax to begin radiative core'
    3387            0 :             relax_to_radiative_core_check_model = terminate
    3388            0 :             s% termination_code = t_relax_finished_okay
    3389            0 :             return
    3390              :          end if
    3391            0 :          min_conv_mx1_bot = rpar(2)
    3392            0 :          if (s% conv_mx1_bot < min_conv_mx1_bot) then
    3393            0 :             min_conv_mx1_bot = s% conv_mx1_bot
    3394            0 :             rpar(2) = min_conv_mx1_bot
    3395              :          end if
    3396            0 :          if (min_conv_mx1_bot < s% job% pre_ms_check_radiative_core_start) then
    3397            0 :             if (s% conv_mx1_bot > s% job% pre_ms_check_radiative_core_stop) then
    3398            0 :                write(*,2) 'finished relax to begin radiative core', s% model_number, s% conv_mx1_bot
    3399            0 :                relax_to_radiative_core_check_model = terminate
    3400            0 :                s% termination_code = t_relax_finished_okay
    3401            0 :             else if (mod(s% model_number, s% terminal_interval) == 0) then
    3402            0 :                write(*,2) 'relative mass of radiative core still tiny', s% model_number, s% conv_mx1_bot
    3403              :             end if
    3404            0 :          else if (mod(s% model_number, s% terminal_interval) == 0) then
    3405            0 :             write(*,2) 'waiting for fully convective core to develop', s% model_number, s% conv_mx1_bot
    3406              :          end if
    3407              :       end function relax_to_radiative_core_check_model
    3408              : 
    3409              : 
    3410            0 :       subroutine do_relax_Z(id, new_z, dlnz, minq, maxq, ierr)
    3411              :          use star_utils, only: eval_current_z
    3412              :          use adjust_xyz, only:set_z
    3413              :          integer, intent(in) :: id
    3414              :          real(dp), intent(in) :: new_z, dlnz, minq, maxq
    3415              :          integer, intent(out) :: ierr
    3416              :          integer, parameter ::  lipar=1, lrpar=5
    3417              :          integer :: max_model_number
    3418              :          real(dp) :: z
    3419              :          type (star_info), pointer :: s
    3420              :          integer, target :: ipar_ary(lipar)
    3421              :          integer, pointer :: ipar(:)
    3422              :          real(dp), target :: rpar_ary(lrpar)
    3423              :          real(dp), pointer :: rpar(:)
    3424            0 :          rpar => rpar_ary
    3425            0 :          ipar => ipar_ary
    3426              :          include 'formats'
    3427              :          ierr = 0
    3428            0 :          if (new_Z < 0 .or. new_Z > 1) then
    3429            0 :             ierr = -1
    3430            0 :             write(*,*) 'invalid new_Z', new_Z
    3431            0 :             return
    3432              :          end if
    3433            0 :          call get_star_ptr(id, s, ierr)
    3434            0 :          if (ierr /= 0) return
    3435            0 :          z = eval_current_z(s, 1, s% nz, ierr)
    3436            0 :          if (ierr /= 0) return
    3437            0 :          if (abs(new_z - z) <= 1d-6*z) return
    3438            0 :          if (max(new_z, z) > 1d-6) then
    3439            0 :             if (abs(new_z - z) <= 1d-3*new_z) then
    3440            0 :                call set_z(s, new_z, 1, s% nz, ierr)
    3441            0 :                return
    3442              :             end if
    3443              :          end if
    3444            0 :          write(*,'(A)')
    3445            0 :          write(*,1) 'current Z', z
    3446            0 :          write(*,1) 'relax to new Z', new_z
    3447            0 :          write(*,1) '(new - current) / current', (new_z - z) / z
    3448            0 :          write(*,'(A)')
    3449            0 :          write(*,1) 'dlnz per step', dlnz
    3450            0 :          write(*,'(A)')
    3451            0 :          rpar(1) = log(max(min_z,new_z))
    3452            0 :          rpar(2) = new_z
    3453            0 :          rpar(3) = abs(dlnz)
    3454            0 :          rpar(4) = minq
    3455            0 :          rpar(5) = maxq
    3456            0 :          max_model_number = s% max_model_number
    3457            0 :          s% max_model_number = -1111
    3458            0 :          s% initial_z = z
    3459              :          call do_internal_evolve( &
    3460              :                id, before_evolve_relax_Z, &
    3461              :                relax_Z_adjust_model, relax_Z_check_model, &
    3462            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    3463            0 :          s% max_model_number = max_model_number
    3464            0 :          call error_check('relax Z',ierr)
    3465              :       end subroutine do_relax_Z
    3466              : 
    3467              : 
    3468            0 :       subroutine before_evolve_relax_Z(s, id, lipar, ipar, lrpar, rpar, ierr)
    3469              :          type (star_info), pointer :: s
    3470              :          integer, intent(in) :: id, lipar, lrpar
    3471              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3472              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3473              :          integer, intent(out) :: ierr
    3474            0 :          ierr = 0
    3475            0 :          call setup_before_relax(s)
    3476            0 :          s% max_model_number = -111
    3477            0 :          s% max_timestep = secyer
    3478            0 :          s% dt_next = s% max_timestep
    3479            0 :       end subroutine before_evolve_relax_Z
    3480              : 
    3481            0 :       integer function relax_Z_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    3482              :          type (star_info), pointer :: s
    3483              :          integer, intent(in) :: id, lipar, lrpar
    3484              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3485              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3486            0 :          relax_Z_adjust_model = keep_going
    3487            0 :       end function relax_Z_adjust_model
    3488              : 
    3489            0 :       integer function relax_Z_check_model(s, id, lipar, ipar, lrpar, rpar)
    3490              :          use adjust_xyz, only: set_z
    3491              :          use star_utils, only: k_for_q, eval_current_z
    3492              :          use do_one_utils, only:do_bare_bones_check_model
    3493              :          type (star_info), pointer :: s
    3494              :          integer, intent(in) :: id, lipar, lrpar
    3495              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3496              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3497              :          integer :: ierr, klo, khi
    3498              :          real(dp) :: lnz_target, new_z, new_lnz, dlnz, lnz, current_z, next_z, &
    3499              :             min_q_for_relax_Z, max_q_for_relax_Z
    3500              : 
    3501              :          logical, parameter :: zdbg = .true.
    3502              : 
    3503              :          include 'formats'
    3504              : 
    3505            0 :          relax_Z_check_model = do_bare_bones_check_model(id)
    3506            0 :          if (relax_Z_check_model /= keep_going) return
    3507              : 
    3508            0 :          lnz_target = rpar(1)
    3509            0 :          new_z = rpar(2)
    3510            0 :          dlnz = rpar(3)
    3511            0 :          min_q_for_relax_Z = rpar(4)
    3512            0 :          max_q_for_relax_Z = rpar(5)
    3513              : 
    3514            0 :          khi = k_for_q(s, min_q_for_relax_Z)
    3515            0 :          klo = k_for_q(s, max_q_for_relax_Z)
    3516            0 :          if (zdbg) write(*,2) 'klo', klo, max_q_for_relax_Z
    3517            0 :          if (zdbg) write(*,2) 'khi', khi, min_q_for_relax_Z
    3518              : 
    3519            0 :          current_z = eval_current_z(s, klo, khi, ierr)
    3520            0 :          if (ierr /= 0) return
    3521              : 
    3522            0 :          if (mod(s% model_number, s% terminal_interval) == 0) &
    3523            0 :             write(*,1) 'new_z, current', new_z, current_z
    3524              : 
    3525            0 :          if (abs(current_z-new_z) <= 1d-6*new_z) then
    3526            0 :             relax_Z_check_model = terminate
    3527            0 :             s% termination_code = t_relax_finished_okay
    3528            0 :             return
    3529              :          end if
    3530              : 
    3531            0 :          lnz = log(max(min_z,current_z))
    3532              : 
    3533              :          if (zdbg) then
    3534            0 :             write(*,1) 'lnz_target', lnz_target
    3535            0 :             write(*,1) 'lnz', lnz
    3536            0 :             write(*,1) 'lnz - lnz_target', lnz - lnz_target
    3537            0 :             write(*,1) 'dlnz', dlnz
    3538              :          end if
    3539              : 
    3540            0 :          if (abs(lnz - lnz_target) < dlnz) then
    3541            0 :             dlnz = abs(lnz - lnz_target)
    3542            0 :             if (zdbg) write(*,1) 'reduced dlnz', dlnz
    3543              :          end if
    3544              : 
    3545            0 :          if (lnz_target < lnz) then
    3546            0 :             new_lnz = lnz - dlnz
    3547              :          else
    3548            0 :             new_lnz = lnz + dlnz
    3549              :          end if
    3550              : 
    3551            0 :          if (zdbg) write(*,1) 'new_lnz', new_lnz
    3552              : 
    3553            0 :          if (new_lnz >= min_dlnz) then
    3554            0 :             next_z = exp(new_lnz)
    3555              :          else
    3556            0 :             next_z = new_z
    3557              :          end if
    3558              : 
    3559            0 :          if (zdbg) write(*,1) 'next_z', next_z
    3560              : 
    3561              :          ierr = 0
    3562            0 :          call set_z(s, next_z, klo, khi, ierr)
    3563            0 :          if (ierr /= 0) then
    3564            0 :             if (s% report_ierr) write(*, *) 'relax_Z_check_model ierr', ierr
    3565            0 :             relax_Z_check_model = terminate
    3566            0 :             s% result_reason = nonzero_ierr
    3567            0 :             return
    3568              :          end if
    3569              : 
    3570            0 :          write(*,1) 'relax Z, z diff, new, current', new_z - current_z, new_z, current_z
    3571              : 
    3572            0 :          if (klo == 1 .and. khi == s% nz) s% initial_z = next_z
    3573            0 :          s% max_timestep = secyer*s% time_step
    3574              : 
    3575            0 :       end function relax_Z_check_model
    3576              : 
    3577              : 
    3578            0 :       subroutine do_relax_Y(id, new_Y, dY, minq, maxq, ierr)
    3579              :          use star_utils, only: k_for_q, eval_current_y
    3580              :          integer, intent(in) :: id
    3581              :          real(dp), intent(in) :: new_Y, dY, minq, maxq
    3582              :          integer, intent(out) :: ierr
    3583              :          integer, parameter ::  lipar=1, lrpar=4
    3584              :          integer :: max_model_number, khi, klo
    3585              :          real(dp) :: y
    3586              :          type (star_info), pointer :: s
    3587              :          integer, target :: ipar_ary(lipar)
    3588              :          integer, pointer :: ipar(:)
    3589              :          real(dp), target :: rpar_ary(lrpar)
    3590              :          real(dp), pointer :: rpar(:)
    3591            0 :          rpar => rpar_ary
    3592            0 :          ipar => ipar_ary
    3593              :          include 'formats'
    3594              :          ierr = 0
    3595            0 :          call get_star_ptr(id, s, ierr)
    3596            0 :          if (ierr /= 0) return
    3597              : 
    3598            0 :          khi = k_for_q(s, minq)
    3599            0 :          klo = k_for_q(s, maxq)
    3600              : 
    3601            0 :          y = eval_current_y(s, klo, khi, ierr)
    3602            0 :          if (ierr /= 0) return
    3603            0 :          if (is_bad(y)) then
    3604            0 :             write(*,1) 'y', y
    3605            0 :             call mesa_error(__FILE__,__LINE__,'do_relax_Y')
    3606              :          end if
    3607              : 
    3608            0 :          if (abs(new_Y - y) <= 1d-6*new_Y) return
    3609            0 :          if (new_Y < 0 .or. new_Y > 1) then
    3610            0 :             ierr = -1
    3611            0 :             write(*,*) 'invalid new_Y', new_Y
    3612            0 :             return
    3613              :          end if
    3614            0 :          write(*,'(A)')
    3615            0 :          write(*,1) 'current Y', Y
    3616            0 :          write(*,1) 'relax to new_Y', new_Y
    3617            0 :          write(*,1) 'dY per step', dY
    3618            0 :          write(*,'(A)')
    3619            0 :          rpar(1) = new_Y
    3620            0 :          rpar(2) = abs(dY)
    3621            0 :          rpar(3) = minq
    3622            0 :          rpar(4) = maxq
    3623            0 :          max_model_number = s% max_model_number
    3624            0 :          s% max_model_number = -1111
    3625            0 :          s% initial_y = y
    3626              :          call do_internal_evolve( &
    3627              :                id, before_evolve_relax_Y, &
    3628              :                relax_Y_adjust_model, relax_Y_check_model, &
    3629            0 :                null_finish_model, .true., lipar, ipar, lrpar, rpar, ierr)
    3630            0 :          s% max_model_number = max_model_number
    3631            0 :          call error_check('relax Y',ierr)
    3632              :       end subroutine do_relax_Y
    3633              : 
    3634              : 
    3635            0 :       subroutine before_evolve_relax_Y(s, id, lipar, ipar, lrpar, rpar, ierr)
    3636              :          type (star_info), pointer :: s
    3637              :          integer, intent(in) :: id, lipar, lrpar
    3638              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3639              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3640              :          integer, intent(out) :: ierr
    3641            0 :          ierr = 0
    3642            0 :          call setup_before_relax(s)
    3643            0 :          s% max_model_number = -111
    3644            0 :          s% max_timestep = secyer
    3645            0 :          s% dt_next = s% max_timestep
    3646            0 :       end subroutine before_evolve_relax_Y
    3647              : 
    3648            0 :       integer function relax_Y_adjust_model(s, id, lipar, ipar, lrpar, rpar)
    3649              :          type (star_info), pointer :: s
    3650              :          integer, intent(in) :: id, lipar, lrpar
    3651              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3652              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3653            0 :          relax_Y_adjust_model = keep_going
    3654            0 :       end function relax_Y_adjust_model
    3655              : 
    3656            0 :       integer function relax_Y_check_model(s, id, lipar, ipar, lrpar, rpar)
    3657              :          use star_utils, only: k_for_q, eval_current_y
    3658              :          use adjust_xyz, only: set_y
    3659              :          use do_one_utils, only: do_bare_bones_check_model
    3660              :          type (star_info), pointer :: s
    3661              :          integer, intent(in) :: id, lipar, lrpar
    3662              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3663              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3664              :          integer :: ierr, klo, khi
    3665              :          real(dp) :: new_y, dy, current_y, next_y, minq, maxq, actual_next_y
    3666              :          logical, parameter :: ydbg = .true.
    3667              :          logical :: end_now
    3668              : 
    3669              :          include 'formats'
    3670              : 
    3671            0 :          end_now=.false.
    3672              : 
    3673            0 :          relax_Y_check_model = do_bare_bones_check_model(id)
    3674            0 :          if (relax_Y_check_model /= keep_going) return
    3675              : 
    3676            0 :          new_y = rpar(1)
    3677            0 :          dy = rpar(2)
    3678            0 :          minq = rpar(3)
    3679            0 :          maxq = rpar(4)
    3680              : 
    3681            0 :          khi = k_for_q(s, minq)
    3682            0 :          klo = k_for_q(s, maxq)
    3683              : 
    3684              :          if (ydbg) then
    3685            0 :             write(*,4) 'klo, khi nz', klo, khi, s% nz
    3686              :          end if
    3687              : 
    3688            0 :          current_y = eval_current_y(s, klo, khi, ierr)
    3689            0 :          if (is_bad(current_y)) then
    3690            0 :             write(*,1) 'current_y', current_y
    3691            0 :             call mesa_error(__FILE__,__LINE__,'relax_y_check_model')
    3692              :          end if
    3693            0 :          if (ierr /= 0) return
    3694              : 
    3695            0 :          if (mod(s% model_number, s% terminal_interval) == 0) then
    3696            0 :             write(*,1) 'new_y', new_y
    3697            0 :             write(*,1) 'dy', dy
    3698            0 :             write(*,1) 'current_y', current_y
    3699            0 :             write(*,1) 'current_y - new_y', current_y - new_y
    3700              :          end if
    3701              : 
    3702            0 :          if (abs(current_y - new_y) < 1d-10) then
    3703            0 :             relax_Y_check_model = terminate
    3704            0 :             s% termination_code = t_relax_finished_okay
    3705            0 :             return
    3706              :          end if
    3707              : 
    3708            0 :          if (abs(current_y - new_y) < dY) then
    3709            0 :             dY = abs(current_y - new_y)
    3710            0 :             end_now = .true.
    3711            0 :             if (ydbg) write(*,1) 'reduced dY', dY
    3712              :          end if
    3713              : 
    3714            0 :          if (new_y >= current_y) then
    3715            0 :             next_y = current_y + dy
    3716              :          else
    3717            0 :             next_y = current_y - dy
    3718              :          end if
    3719              : 
    3720            0 :          if (ydbg) write(*,1) 'next_y', next_y
    3721              : 
    3722              :          ierr = 0
    3723              : 
    3724            0 :          call set_y(s, next_y, klo, khi, ierr)
    3725            0 :          if (ierr /= 0) then
    3726            0 :             if (s% report_ierr) write(*, *) 'relax_Y_check_model ierr', ierr
    3727            0 :             relax_Y_check_model = terminate
    3728            0 :             s% result_reason = nonzero_ierr
    3729            0 :             return
    3730              :          end if
    3731              : 
    3732            0 :          actual_next_y = eval_current_y(s, klo, khi, ierr)
    3733              : 
    3734            0 :          write(*,1) 'relax Y, y diff, new, current', new_y - current_y, new_y, actual_next_y
    3735              : 
    3736            0 :          if (ydbg) write(*,1) 'actual_next_y', actual_next_y
    3737            0 :          if (ydbg) write(*,1) 'actual_next_y - next_y', actual_next_y - next_y
    3738            0 :          if (ydbg) write(*,1) 'y diff', actual_next_y - new_y
    3739              : 
    3740            0 :          if (abs(actual_next_y - new_y) < 1d-10 .or. end_now) then
    3741            0 :             relax_Y_check_model = terminate
    3742            0 :             s% termination_code = t_relax_finished_okay
    3743            0 :             return
    3744              :          end if
    3745              : 
    3746            0 :          if (klo == 1 .and. khi == s% nz) s% initial_y = next_y
    3747            0 :          s% max_timestep = secyer*s% time_step
    3748              : 
    3749            0 :       end function relax_Y_check_model
    3750              : 
    3751              : 
    3752            0 :       subroutine setup_before_relax(s)
    3753              :          type (star_info), pointer :: s
    3754            0 :          s% dxdt_nuc_factor = 0
    3755            0 :          s% max_age = 1d50
    3756            0 :          s% max_age_in_days = 1d50
    3757            0 :          s% max_age_in_seconds = 1d50
    3758            0 :          s% max_timestep_factor = 2
    3759            0 :          s% max_model_number = -1111
    3760            0 :          call turn_off_winds(s)
    3761            0 :       end subroutine setup_before_relax
    3762              : 
    3763              : 
    3764            0 :       subroutine turn_off_winds(s)
    3765              :          type (star_info), pointer :: s
    3766            0 :          s% mass_change = 0
    3767            0 :          s% Reimers_scaling_factor = 0d0
    3768            0 :          s% Blocker_scaling_factor = 0d0
    3769            0 :          s% de_Jager_scaling_factor = 0d0
    3770            0 :          s% van_Loon_scaling_factor = 0d0
    3771            0 :          s% Nieuwenhuijzen_scaling_factor = 0d0
    3772            0 :          s% Vink_scaling_factor = 0d0
    3773            0 :          s% Dutch_scaling_factor = 0d0
    3774            0 :          s% Bjorklund_scaling_factor = 0d0
    3775            0 :          s% use_other_wind = .false.
    3776            0 :       end subroutine turn_off_winds
    3777              : 
    3778              : 
    3779            0 :       subroutine do_internal_evolve( &
    3780              :             id, before_evolve, adjust_model, check_model,&
    3781              :             finish_model, restore_at_end, &
    3782              :             lipar, ipar, lrpar, rpar, ierr)
    3783              :          use evolve
    3784              :          use star_utils, only: yrs_for_init_timestep
    3785              :          use pgstar
    3786              :          use history_specs, only: set_history_columns
    3787              :          use profile, only: set_profile_columns
    3788              :          integer, intent(in) :: id, lipar, lrpar
    3789              :          logical, intent(in) :: restore_at_end
    3790              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3791              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3792              :          interface
    3793              :             subroutine before_evolve(s, id, lipar, ipar, lrpar, rpar, ierr)
    3794              :                use const_def, only: dp
    3795              :                use star_private_def, only:star_info
    3796              :                implicit none
    3797              :                type (star_info), pointer :: s
    3798              :                integer, intent(in) :: id, lipar, lrpar
    3799              :                integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3800              :                real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3801              :                integer, intent(out) :: ierr
    3802              :             end subroutine before_evolve
    3803              :             integer function adjust_model(s, id, lipar, ipar, lrpar, rpar)
    3804              :                use const_def, only: dp
    3805              :                use star_private_def, only:star_info
    3806              :                implicit none
    3807              :                type (star_info), pointer :: s
    3808              :                integer, intent(in) :: id, lipar, lrpar
    3809              :                integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3810              :                real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3811              :             end function adjust_model
    3812              :             integer function check_model(s, id, lipar, ipar, lrpar, rpar)
    3813              :                use const_def, only: dp
    3814              :                use star_private_def, only:star_info
    3815              :                implicit none
    3816              :                type (star_info), pointer :: s
    3817              :                integer, intent(in) :: id, lipar, lrpar
    3818              :                integer, intent(inout), pointer :: ipar(:)  ! (lipar)
    3819              :                real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
    3820              :             end function check_model
    3821              :             integer function finish_model(s)
    3822              :                use star_def, only:star_info
    3823              :                implicit none
    3824              :                type (star_info), pointer :: s
    3825              :             end function finish_model
    3826              :          end interface
    3827              :          integer, intent(out) :: ierr
    3828              :          type (star_info), pointer :: s
    3829              :          character (len=10) :: MLT_option
    3830              :          integer :: result, model_number, model_number_for_last_retry, &
    3831              :             recent_log_header, num_retries, &
    3832              :             photo_interval, profile_interval, priority_profile_interval, &
    3833              :             model_number_old, max_number_retries, &
    3834              :             solver_iters_timestep_limit, iter_for_resid_tol2, iter_for_resid_tol3, &
    3835              :             steps_before_use_gold_tolerances, steps_before_use_gold2_tolerances
    3836              :          real(dp) :: star_age, time, max_age, max_age_in_days, max_age_in_seconds, max_timestep, &
    3837              :             Reimers_scaling_factor, Blocker_scaling_factor, de_Jager_scaling_factor, Dutch_scaling_factor, &
    3838              :             van_Loon_scaling_factor, Nieuwenhuijzen_scaling_factor, Vink_scaling_factor, Bjorklund_scaling_factor,&
    3839              :             dxdt_nuc_factor, tol_correction_norm, tol_max_correction, warning_limit_for_max_residual, &
    3840              :             tol_residual_norm1, tol_max_residual1, &
    3841              :             tol_residual_norm2, tol_max_residual2, &
    3842              :             tol_residual_norm3, tol_max_residual3, &
    3843              :             max_timestep_factor, mass_change, varcontrol_target, dt_next, &
    3844              :             time_old, maxT_for_gold_tolerances
    3845              :          logical :: do_history_file, write_profiles_flag, first_try, use_other_wind, &
    3846              :             use_gold_tolerances, use_gold2_tolerances
    3847              : 
    3848              :          procedure(integer), pointer :: tmp_ptr1 => null(), tmp_ptr3 => null()
    3849              :          procedure(), pointer :: tmp_ptr2 => null(), tmp_ptr4 => null()
    3850              :          logical, parameter :: dbg = .false.
    3851              : 
    3852              :          include 'formats'
    3853              : 
    3854            0 :          ierr = 0
    3855            0 :          call get_star_ptr(id, s, ierr)
    3856            0 :          if (ierr /= 0) return
    3857              : 
    3858            0 :          call save_stuff
    3859              : 
    3860            0 :          s% do_history_file = .false.
    3861            0 :          s% write_profiles_flag = .false.
    3862            0 :          s% warning_limit_for_max_residual = 1d99
    3863            0 :          s% recent_log_header = -1
    3864            0 :          s% max_number_retries = s% relax_max_number_retries
    3865            0 :          s% use_gold_tolerances = s% relax_use_gold_tolerances
    3866            0 :          s% steps_before_use_gold_tolerances = -1
    3867            0 :          s% use_gold2_tolerances = .false.
    3868            0 :          s% steps_before_use_gold2_tolerances = -1
    3869            0 :          if (s% MLT_option == 'TDC') then
    3870            0 :             s% MLT_option = 'Cox'
    3871              :          end if
    3872              : 
    3873            0 :          if (s% relax_solver_iters_timestep_limit /= 0) &
    3874            0 :             s% solver_iters_timestep_limit = s% relax_solver_iters_timestep_limit
    3875              : 
    3876            0 :          if (s% relax_tol_correction_norm /= 0) &
    3877            0 :             s% tol_correction_norm = s% relax_tol_correction_norm
    3878            0 :          if (s% relax_tol_max_correction /= 0) &
    3879            0 :             s% tol_max_correction = s% relax_tol_max_correction
    3880              : 
    3881            0 :          if (s% relax_iter_for_resid_tol2 /= 0) &
    3882            0 :             s% iter_for_resid_tol2 = s% relax_iter_for_resid_tol2
    3883            0 :          if (s% relax_tol_residual_norm1 /= 0) &
    3884            0 :             s% tol_residual_norm1 = s% relax_tol_residual_norm1
    3885            0 :          if (s% relax_tol_max_residual1 /= 0) &
    3886            0 :             s% tol_max_residual1 = s% relax_tol_max_residual1
    3887              : 
    3888            0 :          if (s% relax_iter_for_resid_tol3 /= 0) &
    3889            0 :             s% iter_for_resid_tol3 = s% relax_iter_for_resid_tol3
    3890            0 :          if (s% relax_tol_residual_norm2 /= 0) &
    3891            0 :             s% tol_residual_norm2 = s% relax_tol_residual_norm2
    3892            0 :          if (s% relax_tol_max_residual2 /= 0) &
    3893            0 :             s% tol_max_residual2 = s% relax_tol_max_residual2
    3894              : 
    3895            0 :          if (s% relax_tol_residual_norm3 /= 0) &
    3896            0 :             s% tol_residual_norm3 = s% relax_tol_residual_norm3
    3897            0 :          if (s% relax_tol_max_residual3 /= 0) &
    3898            0 :             s% tol_max_residual3 = s% relax_tol_max_residual3
    3899              : 
    3900            0 :          if (s% relax_maxT_for_gold_tolerances /= 0) &
    3901            0 :             s% maxT_for_gold_tolerances = s% relax_maxT_for_gold_tolerances
    3902              : 
    3903            0 :          if (s% doing_first_model_of_run) then
    3904            0 :             s% num_retries = 0
    3905            0 :             s% time = 0
    3906            0 :             s% star_age = 0
    3907            0 :             s% model_number_for_last_retry = 0
    3908            0 :             s% photo_interval = 0
    3909            0 :             s% profile_interval = 0
    3910            0 :             s% priority_profile_interval = 0
    3911              :          end if
    3912              : 
    3913            0 :          if( s% job% pgstar_flag) then
    3914              :             ! Can't use the star_lib versions otherwise we have a circular dependency in the makefile
    3915            0 :             call set_history_columns(id,s% job% history_columns_file, .true., ierr)
    3916            0 :             if (ierr /= 0) return
    3917            0 :             call set_profile_columns(id, s% job% profile_columns_file, .true., ierr)
    3918            0 :             if (ierr /= 0) return
    3919              :          end if
    3920              : 
    3921            0 :          if (s% doing_first_model_of_run .and. s% job% pgstar_flag) then
    3922            0 :             call do_start_new_run_for_pgstar(s, ierr)
    3923            0 :             if (ierr /= 0) return
    3924              :          end if
    3925              : 
    3926            0 :          call before_evolve(s, id, lipar, ipar, lrpar, rpar, ierr)
    3927            0 :          if (ierr /= 0) then
    3928            0 :             write(*,*) 'failed in before_evolve'
    3929            0 :             return
    3930              :          end if
    3931              : 
    3932            0 :          s% termination_code = -1
    3933            0 :          s% doing_relax = .true.
    3934            0 :          s% need_to_setvars = .true.
    3935              : 
    3936              :          evolve_loop: do  ! evolve one step per loop
    3937              : 
    3938            0 :             first_try = .true.
    3939              : 
    3940            0 :             step_loop: do  ! may need to repeat this loop for retry
    3941              : 
    3942            0 :                result = do_evolve_step_part1(id, first_try)
    3943            0 :                if (result == keep_going) &
    3944            0 :                   result = adjust_model(s, id, lipar, ipar, lrpar, rpar)
    3945            0 :                if (result == keep_going) &
    3946            0 :                   result = do_evolve_step_part2(id, first_try)
    3947              : 
    3948            0 :                if (result == keep_going) result = check_model(s, id, lipar, ipar, lrpar, rpar)
    3949            0 :                if (result == keep_going) result = pick_next_timestep(id)
    3950            0 :                if (result == keep_going) exit step_loop
    3951              : 
    3952            0 :                if (result == retry) then
    3953            0 :                else if (s% result_reason /= result_reason_normal) then
    3954            0 :                   write(*, *) model_number, 'terminate reason: ' // trim(result_reason_str(s% result_reason))
    3955              :                end if
    3956              : 
    3957            0 :                if (result == redo) result = prepare_to_redo(id)
    3958            0 :                if (result == retry) result = prepare_to_retry(id)
    3959            0 :                if (result == terminate) exit evolve_loop
    3960            0 :                first_try = .false.
    3961              : 
    3962              :             end do step_loop
    3963              : 
    3964            0 :             if (.not. s% job% disable_pgstar_during_relax_flag .and. s% job% pgstar_flag) then
    3965              :                ! Can't use the star_lib versions otherwise we have a circular dependency in the makefile
    3966              :                if(dbg) write(*,2) 'after step_loop: call update_pgstar_data', s% model_number
    3967            0 :                call update_pgstar_data(s, ierr)
    3968              :                if (failed()) return
    3969            0 :                call do_read_pgstar_controls(s, s% inlist_fname, ierr)
    3970              :                if (failed()) return
    3971            0 :                call do_pgstar_plots( s, .false., ierr)
    3972              :                if (failed()) return
    3973              :             end if
    3974              : 
    3975            0 :             result = finish_model(s)
    3976            0 :             if (result /= keep_going) exit evolve_loop
    3977              : 
    3978            0 :             tmp_ptr1 => s% how_many_extra_history_columns
    3979            0 :             tmp_ptr2 => s% data_for_extra_history_columns
    3980            0 :             tmp_ptr3 => s% how_many_extra_profile_columns
    3981            0 :             tmp_ptr4 => s% data_for_extra_profile_columns
    3982              : 
    3983            0 :             s% how_many_extra_profile_columns => no_extra_profile_columns
    3984            0 :             s% data_for_extra_profile_columns => none_for_extra_profile_columns
    3985            0 :             s% how_many_extra_history_columns => no_extra_history_columns
    3986            0 :             s% data_for_extra_history_columns => none_for_extra_history_columns
    3987              : 
    3988            0 :             result = finish_step(id, ierr)
    3989            0 :             s% how_many_extra_history_columns => tmp_ptr1
    3990            0 :             s% data_for_extra_history_columns => tmp_ptr2
    3991            0 :             s% how_many_extra_profile_columns => tmp_ptr3
    3992            0 :             s% data_for_extra_profile_columns => tmp_ptr4
    3993            0 :             nullify(tmp_ptr1,tmp_ptr2,tmp_ptr3,tmp_ptr4)
    3994              : 
    3995            0 :             if (result /= keep_going) exit evolve_loop
    3996              : 
    3997            0 :             if (associated(s% finish_relax_step)) then
    3998            0 :                result = s% finish_relax_step(id)
    3999            0 :                if (result /= keep_going) exit evolve_loop
    4000              :             end if
    4001              : 
    4002              :          end do evolve_loop
    4003              : 
    4004            0 :          if (.not. s% job% disable_pgstar_during_relax_flag .and. s% job% pgstar_flag) then
    4005              :          ! Can't use the star_lib versions otherwise we have a circular dependency in the makefile
    4006            0 :             call update_pgstar_data(s, ierr)
    4007            0 :             if (ierr /= 0) return
    4008            0 :             call do_read_pgstar_controls(s, s% inlist_fname, ierr)
    4009            0 :             if (ierr /= 0) return
    4010            0 :             call do_pgstar_plots(s, s% job% save_pgstar_files_when_terminate, ierr)
    4011            0 :             if (ierr /= 0) return
    4012              :          end if
    4013              : 
    4014            0 :          s% doing_relax = .false.
    4015            0 :          s% need_to_setvars = .true.  ! just to be safe
    4016            0 :          s% have_ST_start_info = .false.  ! for ST time smoothing
    4017              : 
    4018            0 :          if (.not. (s% termination_code == t_relax_finished_okay .or. &
    4019            0 :                     s% termination_code == t_extras_check_model)) ierr = -1
    4020              : 
    4021            0 :          s% termination_code = -1
    4022              : 
    4023            0 :          if (associated(s% finished_relax)) call s% finished_relax(id)
    4024              : 
    4025            0 :          if (restore_at_end) call restore_stuff
    4026              : 
    4027            0 :          if (s% job% set_cumulative_energy_error_each_relax) &
    4028            0 :             s% cumulative_energy_error = s% job% new_cumulative_energy_error
    4029              : 
    4030            0 :          s% dt = 0
    4031            0 :          s% dt_old = 0
    4032              : 
    4033            0 :          s% timestep_hold = -100
    4034            0 :          s% model_number_for_last_retry = -100
    4035              : 
    4036              :          contains
    4037              : 
    4038            0 :          logical function failed()
    4039            0 :             failed = .false.
    4040            0 :             if (ierr == 0) return
    4041            0 :             failed = .true.
    4042              :          end function failed
    4043              : 
    4044            0 :          subroutine save_stuff
    4045              : 
    4046            0 :             warning_limit_for_max_residual = s% warning_limit_for_max_residual
    4047            0 :             do_history_file = s% do_history_file
    4048            0 :             write_profiles_flag = s% write_profiles_flag
    4049            0 :             recent_log_header = s% recent_log_header
    4050            0 :             mass_change = s% mass_change
    4051            0 :             Reimers_scaling_factor = s% Reimers_scaling_factor
    4052            0 :             Blocker_scaling_factor = s% Blocker_scaling_factor
    4053            0 :             de_Jager_scaling_factor = s% de_Jager_scaling_factor
    4054            0 :             van_Loon_scaling_factor = s% van_Loon_scaling_factor
    4055            0 :             Nieuwenhuijzen_scaling_factor = s% Nieuwenhuijzen_scaling_factor
    4056            0 :             Vink_scaling_factor = s% Vink_scaling_factor
    4057            0 :             Dutch_scaling_factor = s% Dutch_scaling_factor
    4058            0 :             Bjorklund_scaling_factor = s% Bjorklund_scaling_factor
    4059            0 :             use_other_wind = s% use_other_wind
    4060              : 
    4061            0 :             num_retries = s% num_retries
    4062            0 :             star_age = s% star_age
    4063            0 :             time = s% time
    4064            0 :             model_number = s% model_number
    4065            0 :             dxdt_nuc_factor = s% dxdt_nuc_factor
    4066            0 :             max_age = s% max_age
    4067            0 :             max_age_in_days = s% max_age_in_days
    4068            0 :             max_age_in_seconds = s% max_age_in_seconds
    4069            0 :             max_timestep_factor = s% max_timestep_factor
    4070            0 :             varcontrol_target = s% varcontrol_target
    4071            0 :             max_timestep = s% max_timestep
    4072            0 :             model_number_for_last_retry = s% model_number_for_last_retry
    4073            0 :             photo_interval = s% photo_interval
    4074            0 :             profile_interval = s% profile_interval
    4075            0 :             priority_profile_interval = s% priority_profile_interval
    4076            0 :             dt_next = s% dt_next
    4077            0 :             max_number_retries = s% max_number_retries
    4078            0 :             MLT_option = s% MLT_option
    4079              : 
    4080            0 :             use_gold2_tolerances = s% use_gold2_tolerances
    4081            0 :             steps_before_use_gold2_tolerances = s% steps_before_use_gold2_tolerances
    4082            0 :             use_gold_tolerances = s% use_gold_tolerances
    4083            0 :             steps_before_use_gold_tolerances = s% steps_before_use_gold_tolerances
    4084            0 :             solver_iters_timestep_limit = s% solver_iters_timestep_limit
    4085            0 :             tol_correction_norm = s% tol_correction_norm
    4086            0 :             tol_max_correction = s% tol_max_correction
    4087            0 :             iter_for_resid_tol2 = s% iter_for_resid_tol2
    4088            0 :             tol_residual_norm1 = s% tol_residual_norm1
    4089            0 :             tol_max_residual1 = s% tol_max_residual1
    4090            0 :             iter_for_resid_tol3 = s% iter_for_resid_tol3
    4091            0 :             tol_residual_norm2 = s% tol_residual_norm2
    4092            0 :             tol_max_residual2 = s% tol_max_residual2
    4093            0 :             tol_residual_norm3 = s% tol_residual_norm3
    4094            0 :             tol_max_residual3 = s% tol_max_residual3
    4095            0 :             maxT_for_gold_tolerances = s% maxT_for_gold_tolerances
    4096              : 
    4097              :             ! selected history
    4098            0 :             time_old = s% time_old
    4099            0 :             model_number_old = s% model_number_old
    4100              : 
    4101            0 :          end subroutine save_stuff
    4102              : 
    4103            0 :          subroutine restore_stuff
    4104            0 :             s% warning_limit_for_max_residual = warning_limit_for_max_residual
    4105            0 :             s% do_history_file = do_history_file
    4106            0 :             s% write_profiles_flag = write_profiles_flag
    4107            0 :             s% recent_log_header = recent_log_header
    4108            0 :             s% mass_change = mass_change
    4109            0 :             s% Reimers_scaling_factor = Reimers_scaling_factor
    4110            0 :             s% Blocker_scaling_factor = Blocker_scaling_factor
    4111            0 :             s% de_Jager_scaling_factor = de_Jager_scaling_factor
    4112            0 :             s% van_Loon_scaling_factor = van_Loon_scaling_factor
    4113            0 :             s% Nieuwenhuijzen_scaling_factor = Nieuwenhuijzen_scaling_factor
    4114            0 :             s% Vink_scaling_factor = Vink_scaling_factor
    4115            0 :             s% Dutch_scaling_factor = Dutch_scaling_factor
    4116            0 :             s% Bjorklund_scaling_factor = Bjorklund_scaling_factor
    4117            0 :             s% use_other_wind = use_other_wind
    4118            0 :             s% num_retries = num_retries
    4119            0 :             s% star_age = star_age
    4120            0 :             s% time = time
    4121            0 :             s% model_number = model_number
    4122            0 :             s% dxdt_nuc_factor = dxdt_nuc_factor
    4123            0 :             s% max_age = max_age
    4124            0 :             s% max_age_in_days = max_age_in_days
    4125            0 :             s% max_age_in_seconds = max_age_in_seconds
    4126            0 :             s% max_timestep_factor = max_timestep_factor
    4127            0 :             s% varcontrol_target = varcontrol_target
    4128            0 :             s% max_timestep = max_timestep
    4129            0 :             s% model_number_for_last_retry = model_number_for_last_retry
    4130            0 :             s% photo_interval = photo_interval
    4131            0 :             s% profile_interval = profile_interval
    4132            0 :             s% priority_profile_interval = priority_profile_interval
    4133            0 :             s% dt_next = dt_next
    4134            0 :             s% max_number_retries = max_number_retries
    4135            0 :             s% MLT_option = MLT_option
    4136              : 
    4137            0 :             s% use_gold2_tolerances = use_gold2_tolerances
    4138            0 :             s% steps_before_use_gold2_tolerances = steps_before_use_gold2_tolerances
    4139            0 :             s% use_gold_tolerances = use_gold_tolerances
    4140            0 :             s% steps_before_use_gold_tolerances = steps_before_use_gold_tolerances
    4141            0 :             s% solver_iters_timestep_limit = solver_iters_timestep_limit
    4142            0 :             s% tol_correction_norm = tol_correction_norm
    4143            0 :             s% tol_max_correction = tol_max_correction
    4144            0 :             s% iter_for_resid_tol2 = iter_for_resid_tol2
    4145            0 :             s% tol_residual_norm1 = tol_residual_norm1
    4146            0 :             s% tol_max_residual1 = tol_max_residual1
    4147            0 :             s% iter_for_resid_tol3 = iter_for_resid_tol3
    4148            0 :             s% tol_residual_norm2 = tol_residual_norm2
    4149            0 :             s% tol_max_residual2 = tol_max_residual2
    4150            0 :             s% tol_residual_norm3 = tol_residual_norm3
    4151            0 :             s% tol_max_residual3 = tol_max_residual3
    4152            0 :             s% maxT_for_gold_tolerances = maxT_for_gold_tolerances
    4153              : 
    4154              :             ! selected history
    4155            0 :             s% time_old = time_old
    4156            0 :             s% model_number_old = model_number_old
    4157              : 
    4158            0 :          end subroutine restore_stuff
    4159              : 
    4160              :       end subroutine do_internal_evolve
    4161              : 
    4162              : 
    4163            0 :       integer function null_finish_model(s)
    4164              :          use star_def, only:star_info
    4165              :          type (star_info), pointer :: s
    4166            0 :          null_finish_model = keep_going
    4167            0 :       end function null_finish_model
    4168              : 
    4169              : 
    4170            0 :       integer function no_extra_history_columns(id)
    4171              :          integer, intent(in) :: id
    4172            0 :          no_extra_history_columns = 0
    4173            0 :       end function no_extra_history_columns
    4174              : 
    4175              : 
    4176            0 :       subroutine none_for_extra_history_columns(id, n, names, vals, ierr)
    4177              :          integer, intent(in) :: id, n
    4178              :          character (len=maxlen_history_column_name) :: names(n)
    4179              :          real(dp) :: vals(n)
    4180              :          integer, intent(out) :: ierr
    4181            0 :          ierr = 0
    4182            0 :       end subroutine none_for_extra_history_columns
    4183              : 
    4184              : 
    4185            0 :       integer function no_extra_profile_columns(id)
    4186              :          integer, intent(in) :: id
    4187            0 :          no_extra_profile_columns = 0
    4188            0 :       end function no_extra_profile_columns
    4189              : 
    4190              : 
    4191            0 :       subroutine none_for_extra_profile_columns(id, n, nz, names, vals, ierr)
    4192              :          integer, intent(in) :: id, n, nz
    4193              :          character (len=maxlen_profile_column_name) :: names(n)
    4194              :          real(dp) :: vals(nz,n)
    4195              :          integer, intent(out) :: ierr
    4196            0 :          ierr = 0
    4197            0 :       end subroutine none_for_extra_profile_columns
    4198              : 
    4199            0 :       subroutine error_check(name,ierr)
    4200              :          character(len=*), intent(in) :: name
    4201              :          integer, intent(in) :: ierr
    4202              :          include 'formats'
    4203              : 
    4204            0 :          if (ierr /= 0) then
    4205            0 :             write(*,*) 'failed in ', name
    4206            0 :             return
    4207              :          end if
    4208              : 
    4209            0 :          write(*,'(A)')
    4210            0 :          write(*,*) 'finished doing ', name
    4211            0 :          write(*,'(A)')
    4212              :       end subroutine error_check
    4213              : 
    4214              :       end module relax
        

Generated by: LCOV version 2.0-1