LCOV - code coverage report
Current view: top level - star/private - read_model.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 40.6 % 471 191
Test Date: 2025-10-23 17:17:25 Functions: 46.2 % 13 6

            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 read_model
      21              : 
      22              :       use star_private_def
      23              :       use const_def, only: dp, msun, secyer
      24              : 
      25              :       implicit none
      26              : 
      27              :       integer, parameter :: bit_for_zams_file = 0
      28              :       integer, parameter :: bit_for_lnPgas = 1  ! OBSOLETE: includes lnPgas variables in place of lnd
      29              :       integer, parameter :: bit_for_2models = 2
      30              :       integer, parameter :: bit_for_velocity = 3
      31              :       integer, parameter :: bit_for_rotation = 4
      32              :       integer, parameter :: bit_for_mlt_vc = 5
      33              :       integer, parameter :: bit_for_RSP2 = 6
      34              :       integer, parameter :: bit_for_RTI = 7
      35              :       !integer, parameter ::  = 8
      36              :       integer, parameter :: bit_for_u = 9
      37              :       integer, parameter :: bit_for_D_omega = 10
      38              :       integer, parameter :: bit_for_am_nu_rot = 11
      39              :       integer, parameter :: bit_for_j_rot = 12
      40              :       !integer, parameter ::  = 13
      41              :       !integer, parameter ::  = 14
      42              :       integer, parameter :: bit_for_RSP = 15
      43              :       integer, parameter :: bit_for_no_L_basic_variable = 16
      44              : 
      45              :       integer, parameter :: increment_for_rotation_flag = 1
      46              :       integer, parameter :: increment_for_have_j_rot = 1
      47              :       integer, parameter :: increment_for_have_mlt_vc = 1
      48              :       integer, parameter :: increment_for_D_omega_flag = 1
      49              :       integer, parameter :: increment_for_am_nu_rot_flag = 1
      50              :       integer, parameter :: increment_for_RTI_flag = 1
      51              :       integer, parameter :: increment_for_RSP_flag = 3
      52              :       integer, parameter :: increment_for_RSP2_flag = 1
      53              : 
      54              :       integer, parameter :: max_increment = increment_for_rotation_flag &
      55              :                                           + increment_for_have_j_rot &
      56              :                                           + increment_for_have_mlt_vc &
      57              :                                           + increment_for_D_omega_flag &
      58              :                                           + increment_for_am_nu_rot_flag &
      59              :                                           + increment_for_RTI_flag &
      60              :                                           + increment_for_RSP_flag &
      61              :                                           + increment_for_RSP2_flag
      62              : 
      63              :       integer, parameter :: mesa_zams_file_type = 2**bit_for_zams_file
      64              : 
      65              :       character (len=100000) :: buf
      66              : 
      67              :       contains
      68              : 
      69           18 :       subroutine finish_load_model(s, restart, ierr)
      70              :          use hydro_vars, only: set_vars
      71              :          use star_utils, only: set_m_and_dm, set_m_grav_and_grav, set_dm_bar, &
      72              :             total_angular_momentum, reset_epsnuc_vectors, set_qs
      73              :          use hydro_rotation, only: use_xh_to_update_i_rot_and_j_rot, &
      74              :             set_i_rot_from_omega_and_j_rot, use_xh_to_update_i_rot, set_rotation_info
      75              :          use hydro_RSP2, only: set_RSP2_vars
      76              :          use tdc_hydro, only: set_viscosity_vars_TDC
      77              :          use RSP, only: RSP_setup_part1, RSP_setup_part2
      78              :          use report, only: do_report
      79              :          use alloc, only: fill_ad_with_zeros
      80              :          use brunt, only: do_brunt_B, do_brunt_N2
      81              :          type (star_info), pointer :: s
      82              :          logical, intent(in) :: restart
      83              :          integer, intent(out) :: ierr
      84              :          integer :: k, nz
      85              :          include 'formats'
      86              :          ierr = 0
      87            1 :          nz = s% nz
      88         2465 :          s% brunt_B(1:nz) = 0  ! temporary proxy for brunt_B
      89            1 :          call set_qs(s, nz, s% q, s% dq, ierr)
      90            1 :          if (ierr /= 0) then
      91            0 :             write(*,*) 'set_qs failed in finish_load_model'
      92            0 :             return
      93              :          end if
      94            1 :          call set_m_and_dm(s)
      95            1 :          call set_m_grav_and_grav(s)
      96            1 :          call set_dm_bar(s, nz, s% dm, s% dm_bar)
      97              : 
      98            1 :          call reset_epsnuc_vectors(s)
      99              : 
     100            1 :          s% star_mass = s% mstar/msun
     101              : 
     102            1 :          if (s% rotation_flag) then
     103              :             ! older MESA versions stored only omega in saved models. However, when
     104              :             ! using rotation dependent moments of inertia one actually needs to store
     105              :             ! the angular momentum in order to initialize the model. This flag is here
     106              :             ! to account for the loading of old saved models.
     107            0 :             if (s% have_j_rot) then
     108              :                !if (restart) then
     109              :                   ! only need to compute irot, w_div_w_crit_roche is stored in photos
     110              :                !   call set_i_rot_from_omega_and_j_rot(s)
     111              :                !else
     112              :                   ! need to set w_div_w_crit_roche as well
     113            0 :                call use_xh_to_update_i_rot(s)
     114            0 :                do k=1, s% nz
     115            0 :                   s% omega(k) = s% j_rot(k)/s% i_rot(k)% val
     116              :                end do
     117              :                !end if
     118              :             else
     119              :                ! need to recompute irot and jrot
     120            0 :                call use_xh_to_update_i_rot_and_j_rot(s)
     121              :             end if
     122              :             ! this ensures fp, ft, r_equatorial and r_polar are set by the end
     123              :             !call set_rotation_info(s, .true., ierr)
     124              :             !if (ierr /= 0) then
     125              :             !   write(*,*) &
     126              :             !      'finish_load_model failed in set_rotation_info'
     127              :             !   return
     128              :             !end if
     129              :          end if
     130              : 
     131              :          ! clear some just to avoid getting NaNs at start
     132              :          ! e.g., from profile_starting_model
     133         2465 :          s% D_mix(1:nz) = 0
     134         2465 :          s% adjust_mlt_gradT_fraction(1:nz) = -1
     135         2465 :          s% eps_mdot(1:nz) = 0
     136         2465 :          s% dvc_dt_TDC(1:nz) = 0
     137            1 :          call fill_ad_with_zeros(s% eps_grav_ad,1,-1)
     138         2465 :          s% ergs_error(1:nz) = 0
     139            1 :          if (.not. restart) s% have_ST_start_info = .false.
     140            1 :          if (s% do_element_diffusion) s% edv(:,1:nz) = 0
     141            1 :          if (s% u_flag) then
     142            0 :             call fill_ad_with_zeros(s% u_face_ad,1,-1)
     143            0 :             call fill_ad_with_zeros(s% P_face_ad,1,-1)
     144              :          end if
     145              : 
     146         2465 :          s% flux_limit_R(1:nz) = 0
     147         2465 :          s% flux_limit_lambda(1:nz) = 0
     148              : 
     149            1 :          if (s% RSP_flag) then
     150            0 :             call RSP_setup_part1(s, restart, ierr)
     151            0 :             if (ierr /= 0) then
     152            0 :                write(*,*) 'finish_load_model: RSP_setup_part1 returned ierr', ierr
     153            0 :                return
     154              :             end if
     155              :          end if
     156              : 
     157            1 :          if (.not. s% have_mlt_vc) then
     158            1 :             s% okay_to_set_mlt_vc = .true.
     159              :          end if
     160              : 
     161            1 :          s% doing_finish_load_model = .true.
     162            1 :          call set_vars(s, s% dt, ierr)
     163            1 :          if (ierr == 0 .and. s% RSP2_flag) call set_RSP2_vars(s,ierr)
     164            1 :          if (ierr == 0 .and. s% alpha_TDC_DampM > 0 .and. s% mlt_option == 'TDC') call set_viscosity_vars_TDC(s,ierr)
     165            1 :          s% doing_finish_load_model = .false.
     166            1 :          if (ierr /= 0) then
     167            0 :             write(*,*) 'finish_load_model: failed in set_vars'
     168            0 :             return
     169              :          end if
     170              : 
     171            1 :          if (s% rotation_flag) s% total_angular_momentum = total_angular_momentum(s)
     172              : 
     173            1 :          if (s% RSP_flag) then
     174            0 :             call RSP_setup_part2(s, restart, ierr)
     175            0 :             if (ierr /= 0) then
     176            0 :                write(*,*) 'finish_load_model: RSP_setup_part2 returned ierr', ierr
     177            0 :                return
     178              :             end if
     179              :          end if
     180              : 
     181            1 :          s% doing_finish_load_model = .true.
     182              : 
     183            1 :          if(s% calculate_Brunt_B) call do_brunt_B(s, 1, s%nz, ierr)
     184            1 :          if (ierr /= 0) then
     185            0 :             write(*,*) 'finish_load_model: failed in do_brunt_b'
     186            0 :             return
     187              :          end if
     188              : 
     189            1 :          if(s% calculate_Brunt_N2) call do_brunt_N2(s, 1, s%nz, ierr)
     190            1 :          if (ierr /= 0) then
     191            0 :             write(*,*) 'finish_load_model: failed in do_brunt_N2'
     192            0 :             return
     193              :          end if
     194              : 
     195            1 :          call do_report(s, ierr)
     196            1 :          s% doing_finish_load_model = .false.
     197            1 :          if (ierr /= 0) then
     198            0 :             write(*,*) 'finish_load_model: failed in do_report'
     199            0 :             return
     200              :          end if
     201              : 
     202            1 :       end subroutine finish_load_model
     203              : 
     204              : 
     205            0 :       subroutine do_read_saved_model(s, filename, ierr)
     206            1 :          use utils_lib
     207              :          use utils_def
     208              :          use chem_def
     209              :          use net, only: set_net
     210              :          use alloc, only: set_var_info, &
     211              :             free_star_info_arrays, allocate_star_info_arrays, set_chem_names
     212              :          use star_utils, only: yrs_for_init_timestep, set_phase_of_evolution
     213              :          type (star_info), pointer :: s
     214              :          character (len=*), intent(in) :: filename
     215              :          integer, intent(out) :: ierr
     216              : 
     217              :          integer :: iounit, n, i, t, file_type, &
     218              :             year_month_day_when_created, nz, species, nvar, count
     219              :          logical :: do_read_prev, no_L
     220            0 :          real(dp) :: initial_mass, initial_z, initial_y, &
     221            0 :             tau_factor, Tsurf_factor, opacity_factor, mixing_length_alpha
     222              :          character (len=strlen) :: buffer, string
     223              :          character (len=net_name_len) :: net_name
     224            0 :          character(len=iso_name_length), pointer :: names(:)  ! (species)
     225            0 :          integer, pointer :: perm(:)  ! (species)
     226              : 
     227              :          include 'formats'
     228              : 
     229            0 :          ierr = 0
     230            0 :          open(newunit=iounit, file=trim(filename), status='old', action='read', iostat=ierr)
     231            0 :          if (ierr /= 0) then
     232            0 :             write(*,*) 'open failed', ierr, iounit
     233            0 :             write(*, '(a)') 'failed to open ' // trim(filename)
     234            0 :             return
     235              :          end if
     236              : 
     237              :          ! use token to get file_type so can have comments at start of file
     238            0 :          n = 0
     239            0 :          i = 0
     240            0 :          t = token(iounit, n, i, buffer, string)
     241            0 :          if (t == eof_token) then
     242            0 :             write(*, '(a)') 'failed to find file type at start of ' // trim(filename)
     243            0 :             return
     244              :          end if
     245            0 :          if (t /= name_token) then
     246            0 :             write(*, '(a)') 'failed to find file type at start of ' // trim(filename)
     247            0 :             return
     248              :          end if
     249            0 :          read(string,fmt=*,iostat=ierr) file_type
     250            0 :          if (ierr /= 0) then
     251            0 :             write(*, '(a)') 'failed to find file type at start of ' // trim(filename)
     252            0 :             return
     253              :          end if
     254              : 
     255            0 :          read(iounit, *, iostat=ierr)  ! skip the blank line after the file type
     256            0 :          if (ierr /= 0) then
     257              :             return
     258              :          end if
     259              : 
     260              :          ! refuse to load old models using lnPgas as a structure variable
     261            0 :          if (BTEST(file_type, bit_for_lnPgas)) then
     262            0 :             write(*,'(A)')
     263            0 :             write(*,*) 'MESA no longer supports models using lnPgas as a structure variable'
     264            0 :             write(*,'(A)')
     265            0 :             ierr = -1
     266            0 :             return
     267              :          end if
     268              : 
     269            0 :          s% model_number = 0
     270            0 :          s% star_age = 0
     271            0 :          s% xmstar = -1
     272              : 
     273            0 :          tau_factor = s% tau_factor
     274            0 :          Tsurf_factor = s% Tsurf_factor
     275            0 :          mixing_length_alpha = s% mixing_length_alpha
     276            0 :          opacity_factor = s% opacity_factor
     277              : 
     278              :          call read_properties(iounit, &
     279              :             net_name, species, nz, year_month_day_when_created, &
     280              :             initial_mass, initial_z, initial_y, mixing_length_alpha, &
     281              :             s% model_number, s% star_age, tau_factor, s% Teff, &
     282              :             s% power_nuc_burn, s% power_h_burn, s% power_he_burn, s% power_z_burn, s% power_photo, &
     283              :             Tsurf_factor, opacity_factor, s% crystal_core_boundary_mass, &
     284              :             s% xmstar, s% R_center, s% L_center, s% v_center, &
     285            0 :             s% cumulative_energy_error, s% num_retries, ierr)
     286              : 
     287              :          if (ierr /= 0 .or. initial_mass < 0 .or. nz < 0 &
     288              :                .or. initial_z < 0 .or. species < 0 .or. &
     289            0 :                is_bad(s% xmstar) .or. &
     290              :                is_bad(initial_mass + initial_z)) then
     291            0 :             ierr = -1
     292            0 :             write(*, *) 'do_read_model: missing required properties'
     293            0 :             write(*,*) 'initial_mass', initial_mass
     294            0 :             write(*,*) 'xmstar', s% xmstar
     295            0 :             write(*,*) 'initial_z', initial_z
     296            0 :             write(*,*) 'nz', nz
     297            0 :             write(*,*) 'species', species
     298            0 :             return
     299              :          end if
     300              : 
     301            0 :          s% init_model_number = s% model_number
     302            0 :          s% time = s% star_age*secyer
     303              : 
     304            0 :          if (abs(tau_factor - s% tau_factor) > tau_factor*1d-9 .and. &
     305              :                s% tau_factor /= s% job% set_to_this_tau_factor) then
     306              :             ! don't change if just set by inlist
     307            0 :             write(*,'(A)')
     308            0 :             write(*,1) 'WARNING: changing to saved tau_factor =', tau_factor
     309            0 :             write(*,'(A)')
     310            0 :             s% tau_factor = tau_factor
     311            0 :             s% force_tau_factor = tau_factor
     312              :          end if
     313              : 
     314            0 :          if (abs(Tsurf_factor - s% Tsurf_factor) > Tsurf_factor*1d-9 .and. &
     315              :                s% Tsurf_factor /= s% job% set_to_this_Tsurf_factor) then
     316              :             ! don't change if just set by inlist
     317            0 :             write(*,'(A)')
     318            0 :             write(*,1) 'WARNING: changing to saved Tsurf_factor =', Tsurf_factor
     319            0 :             write(*,'(A)')
     320            0 :             s% Tsurf_factor = Tsurf_factor
     321            0 :             s% force_Tsurf_factor = Tsurf_factor
     322              :          end if
     323              : 
     324            0 :          if (abs(opacity_factor - s% opacity_factor) > opacity_factor*1d-9 .and. &
     325              :                s% opacity_factor /= s% job% relax_to_this_opacity_factor) then
     326              :             ! don't change if just set by inlist
     327            0 :             write(*,'(A)')
     328            0 :             write(*,1) 'WARNING: changing to saved opacity_factor =', opacity_factor
     329            0 :             write(*,'(A)')
     330            0 :             s% opacity_factor = opacity_factor
     331            0 :             s% force_opacity_factor = opacity_factor
     332              :          end if
     333              : 
     334            0 :          if (abs(mixing_length_alpha - s% mixing_length_alpha) > mixing_length_alpha*1d-9) then
     335            0 :             write(*,'(A)')
     336            0 :             write(*,1) 'WARNING: model saved with mixing_length_alpha =', mixing_length_alpha
     337            0 :             write(*,1) 'but current setting for mixing_length_alpha =', s% mixing_length_alpha
     338            0 :             write(*,'(A)')
     339              :          end if
     340              : 
     341            0 :          s% v_flag = BTEST(file_type, bit_for_velocity)
     342            0 :          s% u_flag = BTEST(file_type, bit_for_u)
     343            0 :          s% rotation_flag = BTEST(file_type, bit_for_rotation)
     344            0 :          s% have_j_rot = BTEST(file_type, bit_for_j_rot)
     345            0 :          s% have_mlt_vc = BTEST(file_type, bit_for_mlt_vc)
     346            0 :          s% D_omega_flag = BTEST(file_type, bit_for_D_omega)
     347            0 :          s% am_nu_rot_flag = BTEST(file_type, bit_for_am_nu_rot)
     348            0 :          s% RTI_flag = BTEST(file_type, bit_for_RTI)
     349            0 :          s% RSP_flag = BTEST(file_type, bit_for_RSP)
     350            0 :          s% RSP2_flag = BTEST(file_type, bit_for_RSP2)
     351            0 :          no_L = BTEST(file_type, bit_for_no_L_basic_variable)
     352              : 
     353              :          if (BTEST(file_type, bit_for_lnPgas)) then
     354              :             write(*,'(A)')
     355              :             write(*,*) 'MESA no longer supports models using lnPgas as a structure variable'
     356              :             write(*,'(A)')
     357              :             ierr = -1
     358              :             return
     359              :          end if
     360              : 
     361            0 :          s% net_name = trim(net_name)
     362            0 :          s% species = species
     363            0 :          s% initial_z = initial_z
     364              : 
     365            0 :          s% mstar = initial_mass*Msun
     366            0 :          if (s% xmstar < 0) then
     367            0 :             s% M_center = 0
     368            0 :             s% xmstar = s% mstar
     369              :          else
     370            0 :             s% M_center = s% mstar - s% xmstar
     371              :          end if
     372            0 :          if (is_bad(s% M_center)) then
     373            0 :             write(*,1) 'M_center mstar xmstar initial_mass', &
     374            0 :                s% M_center, s% mstar, s% xmstar, initial_mass
     375            0 :             call mesa_error(__FILE__,__LINE__,'do_read_saved_model')
     376              :          end if
     377              : 
     378            0 :          call set_net(s, s% net_name, ierr)
     379            0 :          if (ierr /= 0) then
     380              :             write(*,*) &
     381            0 :                'do_read_saved_model failed in set_net for net_name = ' // trim(s% net_name)
     382            0 :             return
     383              :          end if
     384              : 
     385            0 :          call set_var_info(s, ierr)
     386            0 :          if (ierr /= 0) then
     387            0 :             write(*,*) 'do_read_saved_model failed in set_var_info'
     388            0 :             return
     389              :          end if
     390              : 
     391              :          ! fixup chem names now that have nvar_hydro
     392            0 :          call set_chem_names(s)
     393              : 
     394            0 :          s% nz = nz
     395            0 :          call free_star_info_arrays(s)
     396            0 :          call allocate_star_info_arrays(s, ierr)
     397            0 :          if (ierr /= 0) then
     398            0 :             write(*,*) 'do_read_saved_model failed in allocate_star_info_arrays'
     399            0 :             return
     400              :          end if
     401              : 
     402            0 :          allocate(names(species), perm(species))
     403            0 :          call get_chem_col_names(s, iounit, species, names, perm, ierr)
     404            0 :          if (ierr /= 0) then
     405            0 :             deallocate(names, perm)
     406            0 :             write(*,*) 'do_read_saved_model failed in get_chem_col_names'
     407            0 :             return
     408              :          end if
     409              : 
     410            0 :          count = 0
     411            0 :          do i=1,species
     412            0 :             if (perm(i)==0) then
     413            0 :                count = count+1
     414            0 :                write(*,*) "Mod file has isotope ",trim(names(i)), " but that is not in the net"
     415              :             end if
     416              :          end do
     417            0 :          if (count/=0) call mesa_error(__FILE__,__LINE__)
     418              : 
     419            0 :          nvar = s% nvar_total
     420              :          call read1_model( &
     421              :                s, s% species, s% nvar_hydro, nz, iounit, &
     422              :                s% xh, s% xa, s% q, s% dq, s% omega, s% j_rot, &
     423            0 :                perm, ierr)
     424            0 :          deallocate(names, perm)
     425            0 :          if (ierr /= 0) then
     426            0 :             write(*,*) 'do_read_saved_model failed in read1_model'
     427            0 :             return
     428              :          end if
     429              : 
     430            0 :          do_read_prev = BTEST(file_type, bit_for_2models)
     431              :          if (ierr == 0) then
     432            0 :             if (do_read_prev) then
     433            0 :                call read_prev
     434              :             else
     435            0 :                s% generations = 1
     436              :             end if
     437              :          end if
     438              : 
     439            0 :          close(iounit)
     440              : 
     441              : 
     442              :          contains
     443              : 
     444              : 
     445            0 :          subroutine read_prev
     446              :             integer :: k
     447              : 
     448            0 :             do k=1, 3
     449            0 :                read(iounit, *, iostat=ierr)
     450            0 :                if (ierr /= 0) return
     451              :             end do
     452            0 :             call read_prev_properties
     453            0 :             if (ierr /= 0) return
     454              : 
     455              :             ! we do read_prev_properties to set initial timestep,
     456              :             ! but we don't use the previous model
     457              :             ! because we need to have other info about that isn't saved
     458              :             ! such as conv_vel and mixing_type
     459              : 
     460            0 :             s% generations = 1
     461              : 
     462            0 :          end subroutine read_prev
     463              : 
     464              : 
     465            0 :          subroutine read_prev_properties
     466              :             character (len=132) :: line
     467            0 :             real(dp) :: tmp, skip_val
     468              :             include 'formats'
     469              : 
     470            0 :             ierr = 0
     471            0 :             s% dt = -1
     472            0 :             s% mstar_old = -1
     473            0 :             s% dt_next = -1
     474            0 :             s% nz_old = -1
     475              : 
     476              :             do  ! until reach a blank line
     477            0 :                read(iounit, fmt='(a)', iostat=ierr) line
     478            0 :                if (ierr /= 0) return
     479              : 
     480            0 :                if (len_trim(line) == 0) exit  ! blank line
     481              : 
     482            0 :                if (match_keyword('previous n_shells', line, tmp)) then
     483            0 :                   s% nz_old = int(tmp)
     484            0 :                   cycle
     485              :                end if
     486              : 
     487            0 :                if (match_keyword('timestep (seconds)', line, s% dt)) then
     488              :                   cycle
     489              :                end if
     490              : 
     491            0 :                if (match_keyword('previous mass (grams)', line, s% mstar_old)) then
     492              :                   cycle
     493              :                end if
     494              : 
     495            0 :                if (match_keyword('dt_next (seconds)', line, s% dt_next)) then
     496              :                   cycle
     497              :                end if
     498              : 
     499            0 :                if (match_keyword('year_month_day_when_created', line, skip_val)) cycle
     500              : 
     501              :             end do
     502            0 :             if (s% dt < 0) then
     503            0 :                ierr = -1
     504            0 :                write(*, *) 'missing dt for previous model'
     505              :             end if
     506            0 :             if (s% mstar_old < 0) then
     507            0 :                ierr = -1
     508            0 :                write(*, *) 'missing mstar_old for previous model'
     509              :             end if
     510            0 :             if (s% dt_next < 0) then
     511            0 :                ierr = -1
     512            0 :                write(*, *) 'missing dt_next for previous model'
     513              :             end if
     514              : 
     515              :          end subroutine read_prev_properties
     516              : 
     517              : 
     518              :       end subroutine do_read_saved_model
     519              : 
     520              : 
     521            2 :       subroutine read1_model( &
     522              :             s, species, nvar_hydro, nz, iounit, &
     523            2 :             xh, xa, q, dq, omega, j_rot, &
     524            2 :             perm, ierr)
     525              :          use star_utils, only: set_qs
     526              :          use chem_def
     527              :          type (star_info), pointer :: s
     528              :          integer, intent(in) :: species, nvar_hydro, nz, iounit, perm(:)
     529              :          real(dp), dimension(:,:), intent(out) :: xh, xa
     530              :          real(dp), dimension(:), intent(out) :: &
     531              :             q, dq, omega, j_rot
     532              :          integer, intent(out) :: ierr
     533              : 
     534              :          integer :: j, k, n, i_lnd, i_lnT, i_lnR, i_lum, i_w, i_Hp, &
     535              :             i_Et_RSP, i_erad_RSP, i_Fr_RSP, i_v, i_u, i_alpha_RTI, ii
     536           46 :          real(dp), target :: vec_ary(species + nvar_hydro + max_increment)
     537              :          real(dp), pointer :: vec(:)
     538              :          integer :: nvec
     539              : 
     540              :          include 'formats'
     541              : 
     542            2 :          ierr = 0
     543            2 :          vec => vec_ary
     544              : 
     545            2 :          i_lnd = s% i_lnd
     546            2 :          i_lnT = s% i_lnT
     547            2 :          i_lnR = s% i_lnR
     548            2 :          i_lum = s% i_lum
     549            2 :          i_w = s% i_w
     550            2 :          i_Hp = s% i_Hp
     551            2 :          i_v = s% i_v
     552            2 :          i_u = s% i_u
     553            2 :          i_alpha_RTI = s% i_alpha_RTI
     554            2 :          i_Et_RSP = s% i_Et_RSP
     555            2 :          i_erad_RSP = s% i_erad_RSP
     556            2 :          i_Fr_RSP = s% i_Fr_RSP
     557              : 
     558              :          n = species + nvar_hydro + 1  ! + 1 is for dq
     559              :          if (s% rotation_flag) n = n+increment_for_rotation_flag  ! read omega
     560              :          if (s% have_j_rot) n = n+increment_for_have_j_rot  ! read j_rot
     561              :          if (s% have_mlt_vc) n = n+increment_for_have_mlt_vc
     562              :          if (s% D_omega_flag) n = n+increment_for_D_omega_flag  ! read D_omega
     563              :          if (s% am_nu_rot_flag) n = n+increment_for_am_nu_rot_flag  ! read am_nu_rot
     564              :          if (s% RTI_flag) n = n+increment_for_RTI_flag  ! read alpha_RTI
     565              :          if (s% RSP_flag) n = n+increment_for_RSP_flag  ! read RSP_et, erad, Fr
     566              :          if (s% RSP2_flag) n = n+increment_for_RSP2_flag  ! read w, Hp
     567              : 
     568            4 : !$omp critical (read1_model_loop)
     569              : ! make this a critical section to so don't have to dynamically allocate buf
     570         4932 :          do k = 1, nz
     571         4930 :             read(iounit,'(a)',iostat=ierr) buf
     572         4930 :             if (ierr /= 0) then
     573            0 :                write(*,3) 'read failed i', k, nz
     574            0 :                exit
     575              :             end if
     576         4930 :             call str_to_vector(buf, vec, nvec, ierr)
     577         4930 :             if (ierr /= 0) then
     578            0 :                write(*,*) 'str_to_vector failed'
     579            0 :                write(*,'(a,i8,1x,a)') 'buf', k, trim(buf)
     580            0 :                exit
     581              :             end if
     582         4930 :             j = int(vec(1))
     583         4930 :             if (j /= k) then
     584            0 :                ierr = -1
     585            0 :                write(*, *) 'error in reading model data   j /= k'
     586            0 :                write(*, *) 'species', species
     587            0 :                write(*, *) 'j', j
     588            0 :                write(*, *) 'k', k
     589            0 :                write(*,'(a,1x,a)') 'buf', trim(buf)
     590            0 :                exit
     591              :             end if
     592              :             j = 1
     593         4930 :             j=j+1; xh(i_lnd,k) = vec(j)
     594         4930 :             j=j+1; xh(i_lnT,k) = vec(j)
     595         4930 :             j=j+1; xh(i_lnR,k) = vec(j)
     596         4930 :             if (s% RSP_flag) then
     597            0 :                j=j+1; xh(i_Et_RSP,k) = vec(j)
     598            0 :                j=j+1; xh(i_erad_RSP,k) = vec(j)
     599            0 :                j=j+1; xh(i_Fr_RSP,k) = vec(j)
     600         4930 :             else if (s% RSP2_flag) then
     601            0 :                j=j+1; xh(i_w,k) = vec(j)
     602            0 :                j=j+1; xh(i_Hp,k) = vec(j)
     603              :             end if
     604         4930 :             if (i_lum /= 0) then
     605         4930 :                j=j+1; xh(i_lum,k) = vec(j)
     606              :             else
     607            0 :                j=j+1; s% L(k) = vec(j)
     608              :             end if
     609         4930 :             j=j+1; dq(k) = vec(j)
     610         4930 :             if (s% v_flag) then
     611            0 :                j=j+1; xh(i_v,k) = vec(j)
     612              :             end if
     613         4930 :             if (s% rotation_flag) then
     614            0 :                j=j+1; omega(k) = vec(j)
     615              :             end if
     616         4930 :             if (s% have_j_rot) then
     617              :                !NOTE: MESA version 10108 was first to store j_rot in saved files
     618            0 :                j=j+1; j_rot(k) = vec(j)
     619              :             end if
     620         4930 :             if (s% D_omega_flag) then
     621            0 :                j=j+1;  ! skip saving the file data
     622              :             end if
     623         4930 :             if (s% am_nu_rot_flag) then
     624            0 :                j=j+1;  ! skip saving the file data
     625              :             end if
     626         4930 :             if (s% u_flag) then
     627            0 :                j=j+1; xh(i_u,k) = vec(j)
     628              :             end if
     629         4930 :             if (s% RTI_flag) then
     630            0 :                j=j+1; xh(i_alpha_RTI,k) = vec(j)
     631              :             end if
     632         4930 :             if (s% have_mlt_vc) then
     633            0 :                j=j+1; s% mlt_vc(k) = vec(j); s% conv_vel(k) = vec(j)
     634              :             end if
     635         4930 :             if (j+species > nvec) then
     636            0 :                ierr = -1
     637            0 :                write(*, *) 'error in reading model data  j+species > nvec'
     638            0 :                write(*, *) 'j+species', j+species
     639            0 :                write(*, *) 'nvec', nvec
     640            0 :                write(*, *) 'j', j
     641            0 :                write(*, *) 'species', species
     642            0 :                write(*,'(a,1x,a)') 'buf', trim(buf)
     643            0 :                exit
     644              :             end if
     645        49302 :             do ii=1,species
     646        44370 :                xa(perm(ii),k) = vec(j+ii)
     647              :             end do
     648              :          end do
     649              : !$omp end critical (read1_model_loop)
     650            2 :          if (ierr /= 0) then
     651            0 :             write(*,*) 'read1_model_loop failed'
     652            0 :             return
     653              :          end if
     654              : 
     655            2 :          if (s% rotation_flag .and. .not. s% D_omega_flag) &
     656            0 :             s% D_omega(1:nz) = 0d0
     657              : 
     658            2 :          if (s% rotation_flag .and. .not. s% am_nu_rot_flag) &
     659            0 :             s% am_nu_rot(1:nz) = 0d0
     660              : 
     661            2 :          call set_qs(s, nz, q, dq, ierr)
     662            2 :          if (ierr /= 0) then
     663            0 :             write(*,*) 'set_qs failed in read1_model sum(dq)', sum(dq(1:nz))
     664            0 :             return
     665              :          end if
     666              : 
     667            2 :       end subroutine read1_model
     668              : 
     669              : 
     670            0 :       subroutine do_read_saved_model_number(fname, model_number, ierr)
     671              :          character (len=*), intent(in) :: fname
     672              :          integer, intent(inout) :: model_number
     673              :          integer, intent(out) :: ierr
     674              :          character (len=strlen) :: net_name
     675              :          integer :: species, n_shells, &
     676              :             num_retries, year_month_day_when_created
     677            0 :          real(dp) :: m_div_msun, initial_z, &
     678            0 :             mixing_length_alpha, star_age, &
     679            0 :             Teff, tau_factor, Tsurf_factor, opacity_factor, crystal_core_boundary_mass, &
     680            0 :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     681            0 :             xmstar, R_center, L_center, v_center, cumulative_energy_error
     682              :          call do_read_saved_model_properties(fname, &
     683              :             net_name, species, n_shells, year_month_day_when_created, &
     684              :             m_div_msun, initial_z, mixing_length_alpha, &
     685              :             model_number, star_age, tau_factor, Teff, &
     686              :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     687              :             Tsurf_factor, opacity_factor, crystal_core_boundary_mass, &
     688              :             xmstar, R_center, L_center, v_center, &
     689            0 :             cumulative_energy_error, num_retries, ierr)
     690            2 :       end subroutine do_read_saved_model_number
     691              : 
     692              : 
     693            0 :       subroutine do_read_saved_model_properties(fname, &
     694              :             net_name, species, n_shells, year_month_day_when_created, &
     695              :             m_div_msun, initial_z, mixing_length_alpha, &
     696              :             model_number, star_age, tau_factor, Teff, &
     697              :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     698              :             Tsurf_factor, opacity_factor, crystal_core_boundary_mass, &
     699              :             xmstar, R_center, L_center, v_center, &
     700              :             cumulative_energy_error, num_retries, ierr)
     701              :          use utils_lib
     702              :          character (len=*), intent(in) :: fname
     703              :          character (len=*), intent(inout) :: net_name
     704              :          integer, intent(inout) :: species, n_shells, &
     705              :             year_month_day_when_created, num_retries, model_number
     706              :          real(dp), intent(inout) :: m_div_msun, initial_z, &
     707              :             mixing_length_alpha, star_age, tau_factor, Teff, &
     708              :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     709              :             Tsurf_factor, opacity_factor, crystal_core_boundary_mass, &
     710              :             xmstar, R_center, L_center, v_center, cumulative_energy_error
     711              :          integer, intent(out) :: ierr
     712              :          integer :: iounit
     713            0 :          real(dp) :: initial_y
     714            0 :          ierr = 0
     715            0 :          open(newunit=iounit, file=trim(fname), action='read', status='old', iostat=ierr)
     716            0 :          if (ierr /= 0) then
     717            0 :             write(*, *) 'failed to open ' // trim(fname)
     718            0 :             return
     719              :          end if
     720            0 :          read(iounit, *, iostat=ierr)
     721            0 :          if (ierr /= 0) then
     722            0 :             close(iounit)
     723            0 :             return
     724              :          end if
     725            0 :          read(iounit, *, iostat=ierr)
     726            0 :          if (ierr /= 0) then
     727            0 :             close(iounit)
     728            0 :             return
     729              :          end if
     730              :          call read_properties(iounit, &
     731              :             net_name, species, n_shells, year_month_day_when_created, &
     732              :             m_div_msun, initial_z, initial_y, mixing_length_alpha, &
     733              :             model_number, star_age, tau_factor, Teff, &
     734              :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     735              :             Tsurf_factor, opacity_factor, crystal_core_boundary_mass, &
     736              :             xmstar, R_center, L_center, v_center, &
     737            0 :             cumulative_energy_error, num_retries, ierr)
     738            0 :          close(iounit)
     739              :       end subroutine do_read_saved_model_properties
     740              : 
     741              : 
     742            0 :       subroutine do_read_net_name(iounit, net_name, ierr)
     743              :          integer, intent(in) :: iounit
     744              :          character (len=*), intent(inout) :: net_name
     745              :          integer, intent(out) :: ierr
     746              :          integer :: species, n_shells, &
     747              :             year_month_day_when_created, model_number, num_retries
     748            0 :          real(dp) :: m_div_msun, initial_z, initial_y, &
     749            0 :             mixing_length_alpha, star_age, tau_factor, Teff, &
     750            0 :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     751            0 :             Tsurf_factor, opacity_factor, crystal_core_boundary_mass, &
     752            0 :             xmstar, R_center, L_center, v_center, cumulative_energy_error
     753              :          call read_properties(iounit, &
     754              :             net_name, species, n_shells, year_month_day_when_created, &
     755              :             m_div_msun, initial_z, initial_y, mixing_length_alpha, &
     756              :             model_number, star_age, tau_factor, Teff, &
     757              :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     758              :             Tsurf_factor, opacity_factor, crystal_core_boundary_mass, &
     759              :             xmstar, R_center, L_center, v_center, &
     760            0 :             cumulative_energy_error, num_retries, ierr)
     761            0 :       end subroutine do_read_net_name
     762              : 
     763              : 
     764            0 :       subroutine do_read_saved_model_age(fname, star_age, ierr)
     765              :          character (len=*), intent(in) :: fname
     766              :          real(dp), intent(inout) :: star_age
     767              :          integer, intent(out) :: ierr
     768              :          character (len=strlen) :: net_name
     769              :          integer :: species, n_shells, model_number, &
     770              :             num_retries, year_month_day_when_created
     771            0 :          real(dp) :: m_div_msun, initial_z, &
     772            0 :             mixing_length_alpha, cumulative_energy_error, &
     773            0 :             Teff, tau_factor, Tsurf_factor, &
     774            0 :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     775            0 :             opacity_factor, crystal_core_boundary_mass, &
     776            0 :             xmstar, R_center, L_center, v_center
     777              :          call do_read_saved_model_properties(fname, &
     778              :             net_name, species, n_shells, year_month_day_when_created, &
     779              :             m_div_msun, initial_z, mixing_length_alpha, &
     780              :             model_number, star_age, tau_factor, Teff, &
     781              :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     782              :             Tsurf_factor, opacity_factor, crystal_core_boundary_mass, &
     783              :             xmstar, R_center, L_center, v_center, &
     784            0 :             cumulative_energy_error, num_retries, ierr)
     785            0 :       end subroutine do_read_saved_model_age
     786              : 
     787              : 
     788           18 :       subroutine read_properties(iounit, &
     789              :             net_name, species, n_shells, year_month_day_when_created, &
     790              :             m_div_msun, initial_z, initial_y, mixing_length_alpha, &
     791              :             model_number, star_age, tau_factor, Teff, &
     792              :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     793              :             Tsurf_factor, opacity_factor, crystal_core_boundary_mass, &
     794              :             xmstar, R_center, L_center, v_center, &
     795              :             cumulative_energy_error, num_retries, ierr)
     796              :          integer, intent(in) :: iounit
     797              :          character (len=*), intent(inout) :: net_name
     798              :          integer, intent(inout) :: species, n_shells, &
     799              :             year_month_day_when_created, model_number, num_retries
     800              :          real(dp), intent(inout) :: m_div_msun, initial_z, initial_y, &
     801              :             mixing_length_alpha, star_age, tau_factor, Teff, &
     802              :             power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, power_photo, &
     803              :             Tsurf_factor, opacity_factor, crystal_core_boundary_mass, &
     804              :             xmstar, R_center, L_center, v_center, cumulative_energy_error
     805              :          integer, intent(out) :: ierr
     806              :          character (len=132) :: line
     807           18 :          real(dp) :: tmp
     808              :          ierr = 0
     809              :          do  ! until reach a blank line
     810           62 :             read(iounit, fmt='(a)', iostat=ierr) line
     811           62 :             if (ierr /= 0) return
     812           62 :             if (len_trim(line) == 0) return  ! blank line
     813           44 :             if (match_keyword_for_string('net_name', line, net_name)) then; cycle; end if
     814           43 :             if (match_keyword('species', line, tmp)) then; species = int(tmp); cycle; end if
     815           42 :             if (match_keyword('n_shells', line, tmp)) then; n_shells = int(tmp); cycle; end if
     816           25 :             if (match_keyword('model_number', line, tmp)) then; model_number = int(tmp); cycle; end if
     817           25 :             if (match_keyword('M/Msun', line, m_div_msun)) cycle
     818            8 :             if (match_keyword('star_age', line, star_age)) cycle
     819            8 :             if (match_keyword('initial_z', line, initial_z)) cycle
     820            7 :             if (match_keyword('initial_y', line, initial_y)) cycle
     821            6 :             if (match_keyword('mixing_length_alpha', line, mixing_length_alpha)) cycle
     822            6 :             if (match_keyword('tau_factor', line, tau_factor)) cycle
     823            6 :             if (match_keyword('Teff', line, Teff)) cycle
     824            6 :             if (match_keyword('power_nuc_burn', line, power_nuc_burn)) cycle
     825            6 :             if (match_keyword('power_h_burn', line, power_h_burn)) cycle
     826            6 :             if (match_keyword('power_he_burn', line, power_he_burn)) cycle
     827            6 :             if (match_keyword('power_z_burn', line, power_z_burn)) cycle
     828            6 :             if (match_keyword('power_photo', line, power_photo)) cycle
     829            6 :             if (match_keyword('Tsurf_factor', line, Tsurf_factor)) cycle
     830            6 :             if (match_keyword('opacity_factor', line, opacity_factor)) cycle
     831            6 :             if (match_keyword('crystal_core_boundary_mass', line, crystal_core_boundary_mass)) cycle
     832            6 :             if (match_keyword('xmstar', line, xmstar)) cycle
     833            6 :             if (match_keyword('R_center', line, R_center)) cycle
     834            6 :             if (match_keyword('L_center', line, L_center)) cycle
     835            6 :             if (match_keyword('v_center', line, v_center)) cycle
     836            6 :             if (match_keyword('cumulative_energy_error', line, cumulative_energy_error)) cycle
     837            6 :             if (match_keyword('year_month_day_when_created', line, tmp)) then
     838            1 :                year_month_day_when_created = int(tmp); cycle; end if
     839            5 :             if (match_keyword('tau_photosphere', line, tmp)) cycle
     840            5 :             if (match_keyword('num_retries', line, tmp)) then; num_retries = int(tmp); cycle; end if
     841              :          end do
     842              :       end subroutine read_properties
     843              : 
     844              : 
     845          270 :       logical function match_keyword(key, txt, value)
     846              :          ! returns true if leading non-blank part of txt is same as key.
     847              :          ! i.e., skips leading blanks in txt before testing equality.
     848              :          character (len=*), intent(in) :: key, txt
     849              :          real(dp), intent(inout) :: value
     850              :          integer :: i, j, k, ierr
     851          270 :          i = len(key)
     852          270 :          k = len(txt)
     853          270 :          j = 1
     854         6028 :          do while (j <= k .and. txt(j:j) == ' ')
     855         6028 :             j = j+1
     856              :          end do
     857          270 :          match_keyword = (txt(j:j+i-1) == key)
     858          270 :          ierr = 0
     859          270 :          if (match_keyword) then
     860           38 :             read(txt(j+i:k), fmt=*, iostat=ierr) value
     861          270 :             if (ierr /= 0) match_keyword = .false.
     862              :          end if
     863          270 :       end function match_keyword
     864              : 
     865              : 
     866           44 :       logical function match_keyword_for_string(key, txt, value)
     867              :          ! returns true if leading non-blank part of txt is same as key.
     868              :          ! i.e., skips leading blanks in txt before testing equality.
     869              :          character (len=*), intent(in) :: key, txt
     870              :          character (len=*), intent(inout) :: value
     871              :          integer :: i, j, k, str_len
     872              :          logical, parameter :: dbg = .false.
     873           44 :          i = len(key)
     874           44 :          k = len(txt)
     875           44 :          j = 1
     876         1099 :          do while (j <= k .and. txt(j:j) == ' ')
     877         1099 :             j = j+1
     878              :          end do
     879           44 :          match_keyword_for_string = (txt(j:j+i-1) == key)
     880           44 :          if (.not. match_keyword_for_string) return
     881              :          if (dbg) then
     882              :             write(*,*) 'matching ' // trim(key)
     883              :             write(*,*) 'txt ' // trim(txt)
     884              :          end if
     885              :          j = j+i
     886            4 :          do while (j <= k .and. txt(j:j) == ' ')
     887            4 :             j = j+1
     888              :          end do
     889            1 :          if (j > k) then
     890           44 :             match_keyword_for_string = .false.
     891              :             if (dbg) write(*,*) 'j > k'
     892              :             return
     893              :          end if
     894            1 :          if (txt(j:j) /= '''') then
     895           44 :             match_keyword_for_string = .false.
     896              :             if (dbg) write(*,*) 'no leading quote'
     897              :             return
     898              :          end if
     899            1 :          j = j+1
     900            1 :          i = 1
     901            1 :          str_len = len(value)
     902           10 :          do while (j <= k .and. txt(j:j) /= '''')
     903            9 :             value(i:i) = txt(j:j)
     904            9 :             i = i+1
     905           10 :             j = j+1
     906              :          end do
     907          248 :          do while (i <= str_len)
     908          247 :             value(i:i) = ' '
     909          247 :             i = i+1
     910              :          end do
     911              :          if (dbg) write(*,*) 'value <' // trim(value) // ">"
     912              :       end function match_keyword_for_string
     913              : 
     914              : 
     915           17 :       subroutine get_chem_col_names(s, iounit, species, names, perm, ierr)
     916              :          use chem_def, only: iso_name_length
     917              :          use chem_lib, only: chem_get_iso_id
     918              :          type (star_info), pointer :: s
     919              :          integer, intent(in) :: iounit, species
     920              :          character(len=iso_name_length), intent(out) :: names(species)
     921              :          integer, intent(out) :: perm(species)
     922              :          integer, intent(out) :: ierr
     923              : 
     924              :          character (len=50000) :: buffer
     925              :          character (len=20) :: string
     926              :          integer :: n, i, j1, j2, str_len, l, indx, j, num_found
     927              : 
     928           17 :          ierr = 0
     929           17 :          read(iounit,fmt='(a)',iostat=ierr) buffer
     930           17 :          if (ierr /= 0) return
     931              : 
     932           17 :          n = len_trim(buffer)
     933           17 :          i = 0
     934           17 :          num_found = 0
     935              :        token_loop: do  ! have non-empty buffer
     936         4964 :             i = i+1
     937         4964 :             if (i > n) then
     938            0 :                write(*,*) 'get_chem_col_names: failed to find all of the names'
     939            0 :                ierr = -1
     940            0 :                return
     941              :             end if
     942         4964 :             if (buffer(i:i) == char(9)) cycle token_loop  ! skip tabs
     943              :             select case(buffer(i:i))
     944              :                case (' ')
     945              :                   cycle token_loop  ! skip spaces
     946              :                case default
     947              :                   j1 = i; j2 = i
     948              :                   name_loop: do
     949          629 :                      if (i+1 > n) exit name_loop
     950          612 :                      if (buffer(i+1:i+1) == ' ') exit name_loop
     951          408 :                      if (buffer(i+1:i+1) == '(') exit name_loop
     952              :                      if (buffer(i+1:i+1) == ')') exit name_loop
     953              :                      if (buffer(i+1:i+1) == ',') exit name_loop
     954              :                      i = i+1
     955          221 :                      j2 = i
     956              :                   end do name_loop
     957          221 :                   str_len = len(string)
     958          221 :                   l = j2-j1+1
     959          221 :                   if (l > str_len) then
     960            0 :                      l = str_len
     961            0 :                      j2 = l+j1-1
     962              :                   end if
     963          221 :                   string(1:l) = buffer(j1:j2)
     964         4012 :                   do j = l+1, str_len
     965         4012 :                      string(j:j) = ' '
     966              :                   end do
     967              : 
     968          221 :                   indx = chem_get_iso_id(string)
     969              : 
     970         5185 :                   if (indx > 0) then
     971          136 :                      num_found = num_found+1
     972          136 :                      names(num_found) = trim(string)
     973          136 :                      perm(num_found) = s% net_iso(indx)
     974              :                      !write(*,*) trim(string), num_found, perm(num_found)
     975          136 :                      if (num_found == species) return
     976              :                   end if
     977              : 
     978              :             end select
     979              :          end do token_loop
     980              : 
     981           17 :       end subroutine get_chem_col_names
     982              : 
     983              :       end module read_model
        

Generated by: LCOV version 2.0-1