LCOV - code coverage report
Current view: top level - star/private - init_model.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 58.6 % 227 133
Test Date: 2025-05-08 18:23:42 Functions: 100.0 % 6 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 init_model
      21              : 
      22              :       use star_private_def
      23              :       use const_def, only: dp, msun, secyer
      24              : 
      25              :       implicit none
      26              : 
      27              :       private
      28              :       public :: get_zams_model
      29              : 
      30              :       integer, parameter :: min_when_created = 20081212
      31              : 
      32              :       contains
      33              : 
      34              :       subroutine get_revised_mass(s, fullname, ierr)
      35              :          use read_model, only: do_read_saved_model
      36              :          use relax, only:do_relax_mass
      37              :          use relax, only: do_relax_Z
      38              :          type (star_info), pointer :: s
      39              :          character (len=*), intent(in) :: fullname
      40              :          integer, intent(out) :: ierr
      41              : 
      42              :          real(dp), parameter :: lg_max_abs_mdot = -3.5d0
      43              :          real(dp) :: init_mass, init_z
      44              : 
      45              :          init_mass = s% initial_mass
      46              :          init_z = s% initial_z
      47              : 
      48              :          call do_read_saved_model(s, fullname, ierr)
      49              :          if (ierr /= 0) return
      50              : 
      51              :          if (abs(s% initial_z - init_z) > 1d-3*init_z) then
      52              :             ierr = -1
      53              :             return
      54              :          end if
      55              : 
      56              :          call do_relax_mass(s% id, init_mass, lg_max_abs_mdot, ierr)
      57              :          if (ierr /= 0) return
      58              : 
      59              :          s% initial_mass = init_mass
      60              :          s% dt_next = min(s% dt_next, 1d2*secyer)
      61              : 
      62              :       end subroutine get_revised_mass
      63              : 
      64              : 
      65            1 :       subroutine get_zams_model(s, zams_filename, ierr)
      66              :          use alloc, only: allocate_star_info_arrays
      67              :          use utils_lib, only: is_bad
      68              :          use relax, only: do_relax_mass
      69              :          type (star_info), pointer :: s
      70              :          character (len=*) :: zams_filename
      71              :          integer, intent(out) :: ierr
      72              : 
      73              :          integer :: nz
      74            1 :          real(dp), dimension(:,:), pointer :: xh, xa
      75            1 :          real(dp), dimension(:), pointer :: q, dq, omega
      76            1 :          real(dp) :: init_mass
      77              :          logical :: in_range
      78              :          real(dp), parameter :: lg_max_abs_mdot = -3.5d0
      79              : 
      80              :          include 'formats'
      81              : 
      82            1 :          ierr = 0
      83            1 :          if (is_bad(s% initial_mass)) then
      84            0 :             write(*,1) 's% initial_mass', s% initial_mass
      85            0 :             call mesa_error(__FILE__,__LINE__,'get_zams_model')
      86              :          end if
      87              : 
      88            1 :          init_mass = s% initial_mass
      89            1 :          s% mstar = s% initial_mass*Msun
      90            1 :          s% xmstar = s% mstar
      91            1 :          s% M_center = 0
      92              : 
      93              :          call get1_zams_model( &
      94              :             s, zams_filename, nz, xh, xa, q, dq, &
      95            1 :             omega, in_range, ierr)
      96            1 :          if (ierr /= 0) then
      97            0 :             write(*,1) 'failed in get1_zams_model'
      98            0 :             call mesa_error(__FILE__,__LINE__,'get_zams_model')
      99              :          end if
     100              : 
     101              : 
     102            1 :          s% nz = nz
     103            1 :          call allocate_star_info_arrays(s, ierr)
     104            1 :          if (ierr /= 0) then
     105            0 :             call dealloc
     106            0 :             return
     107              :          end if
     108              : 
     109              :          ! copy, then deallocate
     110        24641 :          s% xh(:,1:nz) = xh(:,1:nz)
     111        44353 :          s% xa(:,1:nz) = xa(:,1:nz)
     112         4929 :          s% q(1:nz) = q(1:nz)
     113         4929 :          s% dq(1:nz) = dq(1:nz)
     114         4929 :          s% omega(1:nz) = omega(1:nz)
     115              : 
     116            1 :          call dealloc
     117              : 
     118            1 :          if (.not. in_range) then  ! have revised s% initial_mass
     119            0 :             s% mstar = s% initial_mass*Msun
     120            0 :             s% xmstar = s% mstar
     121            0 :             s% M_center = 0
     122            0 :             s% dt_next = 1d2*secyer
     123            0 :             call do_relax_mass(s% id, init_mass, lg_max_abs_mdot, ierr)
     124            0 :             if (ierr /= 0) return
     125            0 :             s% initial_mass = init_mass
     126            0 :             s% dt_next = min(s% dt_next, 1d2*secyer)
     127              :          end if
     128              : 
     129              :          contains
     130              : 
     131            1 :          subroutine dealloc
     132            1 :             deallocate(xh, xa, q, dq, omega)
     133            1 :          end subroutine dealloc
     134              : 
     135              :       end subroutine get_zams_model
     136              : 
     137              : 
     138            1 :       subroutine get1_zams_model( &
     139              :             s, zams_filename, nz, xh, xa, q, dq, &
     140              :             omega, in_range, ierr)
     141              :          use utils_lib
     142              :          use const_def, only: mesa_data_dir
     143              :          use net, only: set_net
     144              :          type (star_info), pointer :: s
     145              :          character (len=*), intent(in) :: zams_filename
     146              :          integer, intent(out) :: nz
     147              :          real(dp), dimension(:,:), pointer :: xh, xa
     148            1 :          real(dp), dimension(:), pointer :: q, dq, omega, j_rot
     149              :          logical, intent(out) :: in_range
     150              :          integer, intent(out) :: ierr
     151              : 
     152              :          integer :: iounit, nz1, nz2, file_type, nvar_hydro, species
     153              :          character (len=250) :: fname, line
     154            1 :          real(dp) :: m1, m2, initial_mass
     155              :          logical :: okay
     156              : 
     157              :          include 'formats'
     158              : 
     159            1 :          ierr = 0
     160            1 :          nz = 0
     161              : 
     162            1 :          fname = zams_filename
     163            1 :          open(newunit=iounit, file=trim(fname), action='read', status='old', iostat=ierr)
     164            1 :          if (ierr /= 0) then
     165            1 :             ierr = 0
     166            1 :             fname = trim(mesa_data_dir) // '/star_data/zams_models/' // trim(zams_filename)
     167            1 :             open(newunit=iounit, file=trim(fname), action='read', status='old', iostat=ierr)
     168            1 :             if (ierr /= 0) then
     169            0 :                write(*, *) 'failed to open ' // trim(zams_filename)
     170            0 :                write(*, *) 'failed to open ' // trim(fname)
     171            0 :                return
     172              :             end if
     173              :          end if
     174              : 
     175            1 :          read(iounit, *, iostat=ierr) file_type
     176            1 :          if (ierr /= 0) then
     177            0 :             write(*, *) 'ERROR: first line needs to contains file type number: ' // trim(fname)
     178            0 :             close(iounit)
     179            0 :             return
     180              :          end if
     181              : 
     182            1 :          initial_mass = s% initial_mass
     183            1 :          nvar_hydro = s% nvar_hydro
     184              : 
     185            1 :          call read_zams_header  ! sets net_name
     186            1 :          if (ierr /= 0) then
     187            0 :             close(iounit)
     188            0 :             write(*,*) 'failed in read_zams_header'
     189            0 :             call mesa_error(__FILE__,__LINE__,'get1_zams_model')
     190            0 :             return
     191              :          end if
     192              : 
     193            1 :          call set_net(s, s% net_name, ierr)
     194            1 :          if (ierr /= 0) then
     195            0 :             write(*,*) 'failed in set_net'
     196            0 :             return
     197              :          end if
     198              : 
     199            1 :          species = s% species
     200              : 
     201              :          ! find mass that is closest to init_m
     202            1 :          m1 = 0
     203            1 :          nz1 = 0
     204            1 :          okay = .false.
     205            1 :          in_range = .true.
     206              : 
     207            1 :          read(iounit, *, iostat=ierr)  ! this is the 'M/Msun n_shells' header line
     208            1 :          if (ierr == 0) then
     209           16 :             index_loop: do
     210           17 :                read(iounit, *, iostat=ierr) m2, nz2
     211           17 :                if (ierr /= 0) exit index_loop
     212           17 :                if (m2 <= 0) then  ! end of list
     213            0 :                   read(iounit, *, iostat=ierr)  ! blank line
     214            0 :                   m2 = m1
     215            0 :                   nz2 = nz1
     216            0 :                   in_range = .false.
     217            0 :                   s% initial_mass = m2
     218            0 :                   initial_mass = m2
     219            0 :                   exit index_loop
     220              :                end if
     221           17 :                if (m2 >= initial_mass) then
     222            1 :                   if (m1 == 0) then
     223            0 :                      m1 = m2
     224            0 :                      nz1 = nz2
     225            0 :                      in_range = .false.
     226            0 :                      s% initial_mass = m2
     227            0 :                      initial_mass = m2
     228              :                   end if
     229              :                   ! skip to end of index
     230              :                   skip_loop: do
     231           20 :                      read(iounit, fmt='(a)', iostat=ierr) line
     232           20 :                      if (len_trim(line) == 0) then  ! blank line indicates end of index
     233            1 :                         okay = .true.
     234              :                         exit index_loop
     235              :                      end if
     236           19 :                      if (ierr /= 0) exit index_loop
     237              :                   end do skip_loop
     238              :                   exit index_loop
     239              :                end if
     240           16 :                m1 = m2
     241           16 :                nz1 = nz2
     242              :             end do index_loop
     243              :          end if
     244              : 
     245            1 :          nz = nz1
     246              : 
     247              :          allocate(xh(nvar_hydro,nz), xa(species,nz), q(nz), dq(nz), &
     248            3 :             omega(nz), j_rot(nz), stat=ierr)
     249            1 :          if (ierr /= 0) then
     250            0 :             close(iounit)
     251            0 :             return
     252              :          end if
     253              : 
     254              :          call get1_mass( &
     255              :                s, iounit, m1, nz1, m2, nz2, initial_mass, &
     256              :                nvar_hydro, species, xh, xa, q, dq, &
     257            1 :                omega, j_rot, ierr)
     258            1 :          if (ierr /= 0) then
     259            0 :             write(*,*) 'failed in get1_mass'
     260            0 :             call mesa_error(__FILE__,__LINE__,'get_zams_model')
     261              :          end if
     262            1 :          close(iounit)
     263            4 :          deallocate(j_rot)
     264              : 
     265              :          contains
     266              : 
     267            1 :          subroutine read_zams_header
     268            1 :             use read_model, only: read_properties
     269              :             integer :: year_month_day_when_created, iprop
     270            1 :             real(dp) :: dprop, initial_z, initial_y
     271            1 :             read(iounit, *, iostat=ierr)  ! skip blank line before property list
     272              :             include 'formats'
     273            1 :             if (ierr /= 0) return
     274            1 :             year_month_day_when_created = -1
     275              : 
     276              : 
     277              :             call read_properties(iounit, &
     278              :                s% net_name, iprop, iprop, year_month_day_when_created, &
     279              :                dprop, initial_z, initial_y, &
     280              :                dprop, iprop, dprop, dprop, &
     281              :                dprop, dprop, dprop, dprop, &
     282              :                dprop, dprop, dprop, dprop, dprop, dprop, &
     283            1 :                dprop, dprop, dprop, dprop, iprop, ierr)
     284            1 :             if (ierr /= 0) then
     285            0 :                write(*,2) 'year_month_day_when_created', year_month_day_when_created
     286            0 :                write(*,*) 'net_name' // trim(s% net_name)
     287            0 :                call mesa_error(__FILE__,__LINE__,'read_zams_header')
     288            0 :                return
     289              :             end if
     290              : 
     291            1 :             if (year_month_day_when_created < min_when_created) then
     292            0 :                ierr = -1
     293            0 :                write(*, *)
     294            0 :                write(*, *)
     295            0 :                write(*, *)
     296            0 :                write(*, *) 'sorry: you need to update the zams data file.'
     297            0 :                write(*, *) 'found "year_month_day_when_created" =', year_month_day_when_created
     298            0 :                write(*, *) 'but need at least', min_when_created
     299            0 :                write(*, *)
     300            0 :                write(*, *)
     301            0 :                write(*, *)
     302            0 :                return
     303              :             end if
     304            1 :             if (abs(initial_z - s% initial_z) > 1d-3*s% initial_z) then
     305            0 :                ierr = -1
     306            0 :                write(*, *)
     307            0 :                write(*, *)
     308            0 :                write(*, *)
     309            0 :                write(*, *) 'WARNING: requested initial_z does not match zams file initial_z.'
     310            0 :                write(*, 1) 'zams file initial_z', initial_z
     311            0 :                write(*, 1) 'requested initial_z', s% initial_z
     312            0 :                write(*, *)
     313            0 :                write(*, *)
     314            0 :                write(*, *)
     315            0 :                return
     316              :             end if
     317            1 :             if (s% initial_y > 0 .and. &
     318              :                   abs(initial_y - s% initial_y) > 1d-3*s% initial_y) then
     319            0 :                ierr = -1
     320            0 :                write(*, *)
     321            0 :                write(*, *)
     322            0 :                write(*, *)
     323            0 :                write(*, *) 'WARNING: requested initial_y does not match zams file initial_y.'
     324            0 :                write(*, 1) 'zams file initial_y', initial_y
     325            0 :                write(*, 1) 'requested initial_y', s% initial_y
     326            0 :                write(*, *)
     327            0 :                write(*, *)
     328            0 :                write(*, *)
     329            0 :                return
     330              :             end if
     331            1 :          end subroutine read_zams_header
     332              : 
     333              :       end subroutine get1_zams_model
     334              : 
     335              : 
     336            1 :       subroutine get1_mass( &
     337              :             s, iounit, m1, nz1, m2, nz2, initial_mass, &
     338            1 :             nvar_hydro, species, xh, xa, q, dq, &
     339            1 :             omega, j_rot, ierr)
     340              :          use read_model, only: read_properties, read1_model
     341              :          use chem_def, only: iso_name_length
     342              :          use read_model, only: get_chem_col_names
     343              :          use star_utils, only: interp_q
     344              :          type (star_info), pointer :: s
     345              :          integer, intent(in) :: iounit, nz1, nz2, nvar_hydro, species
     346              :          real(dp), intent(in) :: m1, m2, initial_mass
     347              :          real(dp), intent(inout) :: xh(:,:)  ! (nvar_hydro,nz1)
     348              :          real(dp), intent(inout) :: xa(:,:)  ! (species,nz1)
     349              :          real(dp), intent(inout), dimension(:) :: &
     350              :             q, dq, omega, j_rot  ! (nz1)
     351              :          integer, intent(out) :: ierr
     352              : 
     353              :          integer :: i, k, nz, nz_in, iprop
     354            1 :          real(dp) :: m_in, m_read, dprop, lnm1, lnm2
     355            1 :          real(dp), dimension(:, :), pointer :: xh2, xa2
     356              :          real(dp), dimension(:), pointer :: &
     357            1 :             q2, dq2, omega2, j_rot2
     358           14 :          real(dp) :: alfa, struct(nvar_hydro), comp(species)
     359              :          logical :: okay
     360              :          character (len=net_name_len) :: net_name
     361            1 :          character(len=iso_name_length), pointer :: names(:)  ! (species)
     362            1 :          integer, pointer :: perm(:)  ! (species)
     363              : 
     364              :          include 'formats'
     365              : 
     366            1 :          nz = nz1
     367            1 :          m_read = m1
     368              : 
     369              :          allocate( &
     370              :             xh2(nvar_hydro, nz2), xa2(species, nz2), q2(nz2), dq2(nz2), &
     371              :             omega2(nz2), j_rot2(nz2), &
     372            3 :             names(species), perm(species), stat=ierr)
     373            1 :          if (ierr /= 0) return
     374              :          okay = .false.
     375           17 :          mass_loop: do  ! loop until find desired mass
     376              : 
     377           17 :             m_in = -1; nz_in = -1; net_name = ''
     378              :             call read_properties(iounit, &
     379              :                net_name, iprop, nz_in, iprop, m_in, &
     380              :                dprop, dprop, dprop, iprop, &
     381              :                dprop, dprop, dprop, dprop, dprop, &
     382              :                dprop, dprop, dprop, dprop, dprop, dprop, &
     383           17 :                dprop, dprop, dprop, dprop, dprop, iprop, ierr)
     384           17 :             if (ierr /= 0 .or. m_in < 0 .or. nz_in < 0) then
     385            0 :                write(*,*) 'missing required properties'
     386            0 :                write(*,*) 'ierr', ierr
     387            0 :                write(*,*) 'm_in', m_in
     388            0 :                write(*,*) 'nz_in', nz_in
     389            0 :                ierr = -1
     390            0 :                exit mass_loop
     391              :             end if
     392              : 
     393           17 :             call get_chem_col_names(s, iounit, species, names, perm, ierr)
     394           17 :             if (ierr /= 0) exit mass_loop
     395              : 
     396           17 :             if (abs(m_in-m_read) > 1d-4) then
     397              : 
     398        50344 :                do i = 1, nz_in  ! skip this one
     399        50329 :                   read(iounit, *, iostat=ierr)
     400        50344 :                   if (ierr /= 0) exit mass_loop
     401              :                end do
     402              : 
     403              :             else  ! store this one
     404              : 
     405            2 :                if (nz /= nz_in) then
     406              :                   write(*, '(a, 2i6)') &
     407            0 :                      'nz /= nz_in: logic error in routine for reading model file', nz, nz_in
     408            0 :                   ierr = -1
     409            0 :                   return
     410              :                end if
     411              : 
     412            2 :                if (m_read == m1) then
     413              :                   call read1_model( &
     414              :                      s, species, nvar_hydro, nz, iounit, &
     415            1 :                      xh, xa, q, dq, omega, j_rot, perm, ierr)
     416            1 :                   if (ierr /= 0) exit mass_loop
     417            1 :                   okay = .true.
     418            1 :                   if (m2 == m1) exit mass_loop
     419            1 :                   m_read = m2
     420            1 :                   nz = nz2
     421              :                else
     422              :                   call read1_model( &
     423              :                      s, species, nvar_hydro, nz, iounit, &
     424            1 :                      xh2, xa2, q2, dq2, omega2, j_rot2, perm, ierr)
     425            1 :                   if (ierr /= 0) exit mass_loop
     426            1 :                   okay = .true.
     427            1 :                   nz = nz1
     428              :                   exit mass_loop
     429              :                end if
     430              : 
     431              :             end if
     432           16 :             read(iounit, *, iostat=ierr)  ! skip line following the last zone
     433           16 :             if (ierr /= 0) exit mass_loop
     434              : 
     435              :          end do mass_loop
     436              : 
     437            0 :          if (.not. okay) then
     438            0 :             ierr = -1
     439            0 :             call dealloc
     440            0 :             return
     441              :          end if
     442              : 
     443            2 :          if (m1 /= m2) then  ! interpolate linearly in log(m)
     444            1 :             lnm1 = log(m1)
     445            1 :             lnm2 = log(m2)
     446            1 :             alfa = (log(initial_mass) - lnm2) / (lnm1 - lnm2)
     447         2465 :             do k=1,nz1
     448              :                call interp_q( &
     449         2464 :                   nz2, nvar_hydro, species, q(k), xh2, xa2, q2, dq2, struct, comp, ierr)
     450         2464 :                if (ierr /= 0) then
     451            0 :                   call dealloc
     452            0 :                   return
     453              :                end if
     454        12320 :                xh(1:nvar_hydro,k) = alfa*xh(1:nvar_hydro,k) + (1-alfa)*struct(1:nvar_hydro)
     455        22177 :                xa(1:species,k) = alfa*xa(1:species,k) + (1-alfa)*comp(1:species)
     456              :             end do
     457            1 :             call dealloc
     458              :          end if
     459              : 
     460              :          contains
     461              : 
     462            1 :          subroutine dealloc
     463            1 :             deallocate(xh2, xa2, q2, dq2, omega2, j_rot2, names, perm)
     464            1 :          end subroutine dealloc
     465              : 
     466              :       end subroutine get1_mass
     467              : 
     468              :       end module init_model
        

Generated by: LCOV version 2.0-1