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

Generated by: LCOV version 2.0-1