LCOV - code coverage report
Current view: top level - star/private - pgstar_support.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 1.1 % 885 10
Test Date: 2025-05-08 18:23:42 Functions: 1.7 % 60 1

            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 pgstar_support
      21              : 
      22              :    use star_private_def
      23              :    use const_def, only: dp, secday, secyer, mesa_data_dir, &
      24              :       overshoot_mixing, rotation_mixing, thermohaline_mixing, semiconvective_mixing, &
      25              :       leftover_convective_mixing, convective_mixing, no_mixing
      26              :    use rates_def, only : i_rate
      27              :    use utils_lib
      28              :    use star_pgstar
      29              : 
      30              :    implicit none
      31              : 
      32              :    integer, parameter :: category_offset = 1000
      33              :    integer, parameter :: abundance_offset = 2000
      34              :    integer, parameter :: extras_offset = 3000
      35              : 
      36              :    logical :: have_initialized_pgstar = .false.
      37              : 
      38              :    real :: sum_dHR_since_last_file_write
      39              : 
      40              : 
      41              :    ! lines for TRho profile
      42              :    real, dimension(:), allocatable :: hydrogen_burn_logT, hydrogen_burn_logRho
      43              :    real, dimension(:), allocatable :: helium_burn_logT, helium_burn_logRho
      44              :    real, dimension(:), allocatable :: carbon_burn_logT, carbon_burn_logRho
      45              :    real, dimension(:), allocatable :: oxygen_burn_logT, oxygen_burn_logRho
      46              :    real, dimension(:), allocatable :: psi4_logT, psi4_logRho
      47              :    real, dimension(:), allocatable :: elect_data_logT, elect_data_logRho
      48              :    real, dimension(:), allocatable :: gamma_4_thirds_logT, gamma_4_thirds_logRho
      49              :    real, dimension(:), allocatable :: kap_rad_cond_eq_logT, kap_rad_cond_eq_logRho
      50              :    real, dimension(:), allocatable :: opal_clip_logT, opal_clip_logRho
      51              :    real, dimension(:), allocatable :: scvh_clip_logT, scvh_clip_logRho
      52              : 
      53              :    ! Tioga line types
      54              :    integer, parameter :: Line_Type_Solid = 1
      55              :    integer, parameter :: Line_Type_Dash = 2
      56              :    integer, parameter :: Line_Type_Dot_Dash = 3
      57              :    integer, parameter :: Line_Type_Dot = 4
      58              : 
      59              : contains
      60              : 
      61              : 
      62            0 :    subroutine add_to_pgstar_hist(s, pg_hist_new)
      63              :       type (star_info), pointer :: s
      64              :       type (pgstar_hist_node), pointer :: pg_hist_new
      65              :       type (pgstar_hist_node), pointer :: next => null()
      66              :       integer :: step
      67            0 :       step = pg_hist_new% step
      68            0 :       do
      69            0 :          if (.not. associated(s% pg% pgstar_hist)) then
      70            0 :             s% pg% pgstar_hist => pg_hist_new
      71            0 :             nullify(pg_hist_new% next)
      72            0 :             return
      73              :          end if
      74            0 :          if (step > s% pg% pgstar_hist% step) then
      75            0 :             pg_hist_new% next => s% pg% pgstar_hist
      76            0 :             s% pg% pgstar_hist => pg_hist_new
      77            0 :             return
      78              :          end if
      79              :          ! discard item
      80            0 :          next => s% pg% pgstar_hist% next
      81            0 :          deallocate(s% pg% pgstar_hist% vals)
      82            0 :          deallocate(s% pg% pgstar_hist)
      83            0 :          s% pg% pgstar_hist => next
      84              :       end do
      85              :    end subroutine add_to_pgstar_hist
      86              : 
      87              : 
      88            2 :    subroutine pgstar_clear(s)
      89              :       type (star_info), pointer :: s
      90              :       integer :: i
      91              :       type (pgstar_win_file_data), pointer :: p
      92              :       type (pgstar_hist_node), pointer :: pg_hist => null(), next => null()
      93            2 :       pg_hist => s% pg% pgstar_hist
      94            2 :       do while(associated(pg_hist))
      95            0 :          if (associated(pg_hist% vals)) deallocate(pg_hist% vals)
      96            0 :          next => pg_hist% next
      97            0 :          deallocate(pg_hist)
      98            0 :          pg_hist => next
      99              :       end do
     100            2 :       nullify(s% pg% pgstar_hist)
     101            2 :       if (have_initialized_pgstar) return
     102          196 :       do i = 1, num_pgstar_plots
     103          194 :          p => s% pg% pgstar_win_file_ptr(i)
     104          194 :          p% id_win = 0
     105          194 :          p% have_called_mkdir = .false.
     106          196 :          p% file_dir_for_previous_mkdir = ''
     107              :       end do
     108              :    end subroutine pgstar_clear
     109              : 
     110              : 
     111            0 :    subroutine init_pgstar(ierr)
     112              :       integer, intent(out) :: ierr
     113              : 
     114            0 :       if (have_initialized_pgstar) return
     115              : 
     116            0 :       call read_support_info(ierr)
     117            0 :       if (failed('read_support_info')) return
     118              : 
     119            0 :       have_initialized_pgstar = .true.
     120            0 :       sum_dHR_since_last_file_write = 0
     121              : 
     122              :    contains
     123              : 
     124            0 :       logical function failed(str)
     125              :          character (len = *), intent(in) :: str
     126            0 :          failed = (ierr /= 0)
     127            0 :          if (failed) then
     128            0 :             write(*, *) trim(str) // ' ierr', ierr
     129              :          end if
     130            0 :       end function failed
     131              : 
     132              :    end subroutine init_pgstar
     133              : 
     134            0 :    subroutine check_window(s, p, ierr)
     135              :       type (star_info), pointer :: s
     136              :       type (pgstar_win_file_data), pointer :: p
     137              :       integer, intent(out) :: ierr
     138            0 :       ierr = 0
     139            0 :       if (p% do_win .and. (.not. p% win_flag)) then
     140            0 :          p% do_win = .false.
     141            0 :          if (p% id_win > 0) then
     142            0 :             call pgslct(p% id_win)
     143            0 :             call pgclos
     144            0 :             p% id_win = 0
     145              :          end if
     146            0 :       else if (p% win_flag .and. (.not. p% do_win)) then
     147            0 :          if (p% id_win == 0) &
     148            0 :             call open_device(s, p, .false., '/xwin', p% id_win, ierr)
     149            0 :          if (ierr == 0 .and. p% id_win > 0) p% do_win = .true.
     150              :       end if
     151            0 :       if (p% do_win .and. p% id_win > 0 .and. &
     152              :          (p% win_width /= p% prev_win_width .or. &
     153              :             p% win_aspect_ratio /= p% prev_win_aspect_ratio)) then
     154            0 :          call pgslct(p% id_win)
     155            0 :          call pgpap(p% win_width, p% win_aspect_ratio)
     156            0 :          p% prev_win_width = p% win_width
     157            0 :          p% prev_win_aspect_ratio = p% win_aspect_ratio
     158              :       end if
     159            0 :    end subroutine check_window
     160              : 
     161              : 
     162            0 :    subroutine check_file(s, p, ierr)
     163              :       use utils_lib, only : mkdir
     164              :       type (star_info), pointer :: s
     165              :       type (pgstar_win_file_data), pointer :: p
     166              :       integer, intent(out) :: ierr
     167              :       character (len = strlen) :: name
     168            0 :       ierr = 0
     169            0 :       if (p% do_file .and. (.not. p% file_flag)) then
     170            0 :          p% do_file = .false.
     171            0 :       else if (p% file_flag .and. (.not. p% do_file)) then
     172            0 :          if (p% id_file == 0) then
     173            0 :             if (.not. p% have_called_mkdir .or. &
     174              :                p% file_dir /= p% file_dir_for_previous_mkdir) then
     175            0 :                if(.not. folder_exists(trim(p% file_dir))) call mkdir(trim(p% file_dir))
     176            0 :                p% have_called_mkdir = .true.
     177            0 :                p% file_dir_for_previous_mkdir = p% file_dir
     178              :             end if
     179            0 :             call create_file_name(s, p% file_dir, p% file_prefix, name)
     180            0 :             name = trim(name) // '/' // trim(s% pg% file_device)
     181            0 :             call open_device(s, p, .true., name, p% id_file, ierr)
     182            0 :             if (ierr /= 0) return
     183            0 :             p% most_recent_filename = name
     184              :          end if
     185            0 :          p% do_file = .true.
     186              :       end if
     187              :    end subroutine check_file
     188              : 
     189              : 
     190            0 :    subroutine create_file_name(s, dir, prefix, name)
     191              :       use star_utils, only : get_string_for_model_number
     192              :       type (star_info), pointer :: s
     193              :       character (len = *), intent(in) :: dir, prefix
     194              :       character (len = *), intent(out) :: name
     195              :       character (len = strlen) :: num_str, fstring
     196              :       character (len = 32) :: file_extension
     197            0 :       write(fstring, '( "(i",i2.2,".",i2.2,")" )') s% pg% file_digits, s% pg% file_digits
     198            0 :       write(num_str, fstring) s% model_number
     199            0 :       if (len_trim(dir) > 0) then
     200            0 :          name = trim(dir) // '/' // trim(prefix)
     201              :       else
     202            0 :          name = prefix
     203              :       end if
     204            0 :       if (s%pg%file_device=='vcps') then
     205            0 :          file_extension = 'ps'
     206              :       else
     207            0 :          file_extension = s%pg%file_device  ! e.g.: png, ps
     208              :       end if
     209            0 :       name = trim(name) // trim(num_str) // '.' // trim(file_extension)
     210            0 :    end subroutine create_file_name
     211              : 
     212              : 
     213            0 :    subroutine write_plot_to_file(s, p, filename, ierr)
     214              :       type (star_info), pointer :: s
     215              :       type (pgstar_win_file_data), pointer :: p
     216              :       character (len = *), intent(in) :: filename
     217              :       integer, intent(out) :: ierr
     218              :       character (len = strlen) :: name
     219            0 :       ierr = 0
     220              :       !name = trim(filename) // '/' // trim(s% pg% file_device)
     221            0 :       name = trim(filename) // '/png'
     222            0 :       write(*, '(a)') 'write_plot_to_file device: ' // trim(name)
     223            0 :       call open_device(s, p, .true., trim(name), p% id_file, ierr)
     224            0 :       if (ierr /= 0) then
     225            0 :          write(*, *) 'failed in open_device'
     226            0 :          return
     227              :       end if
     228            0 :       call p% plot(s% id, p% id_file, ierr)
     229            0 :       call pgclos
     230            0 :       p% id_file = 0
     231            0 :       p% do_file = .false.
     232            0 :    end subroutine write_plot_to_file
     233              : 
     234              : 
     235            0 :    subroutine open_device(s, p, is_file, dev, id, ierr)
     236              :       use pgstar_colors, only: set_device_colors
     237              :       type (star_info), pointer :: s
     238              :       type (pgstar_win_file_data), pointer :: p
     239              :       logical, intent(in) :: is_file
     240              :       character (len = *), intent(in) :: dev
     241              :       integer, intent(out) :: id
     242              :       integer, intent(out) :: ierr
     243              : 
     244              :       integer :: pgopen
     245              :       character (len = strlen) :: dir
     246              :       logical :: white_on_black_flag
     247            0 :       real :: width, ratio
     248              : 
     249            0 :       if (is_file) then
     250            0 :          dir = p% file_dir
     251            0 :          white_on_black_flag = s% pg% file_white_on_black_flag
     252              :       else
     253            0 :          dir = ''
     254            0 :          white_on_black_flag = s% pg% win_white_on_black_flag
     255              :       end if
     256              : 
     257            0 :       ierr = 0
     258            0 :       id = -1
     259            0 :       id = pgopen(trim(dev))
     260            0 :       if (id <= 0) return
     261              : 
     262              :       !write(*,*) 'open device <' // trim(dev) // '> ' // trim(p% name), id
     263            0 :       if (is_file) then
     264            0 :          width = p% file_width; if (width < 0) width = p% win_width
     265            0 :          ratio = p% file_aspect_ratio; if (ratio < 0) ratio = p% win_aspect_ratio
     266            0 :          call pgpap(width, ratio)
     267              :       else
     268            0 :          call pgpap(p% win_width, p% win_aspect_ratio)
     269            0 :          p% prev_win_width = p% win_width
     270            0 :          p% prev_win_aspect_ratio = p% win_aspect_ratio
     271              :       end if
     272            0 :       call set_device_colors(white_on_black_flag)
     273              :    end subroutine open_device
     274              : 
     275              : 
     276            0 :    subroutine read_support_info(ierr)
     277              :       integer, intent(out) :: ierr
     278              : 
     279              :       ierr = 0
     280              : 
     281              :       call read_TRho_data(&
     282            0 :          'hydrogen_burn.data', hydrogen_burn_logT, hydrogen_burn_logRho, ierr)
     283            0 :       if (ierr /= 0) then
     284            0 :          write(*, *) 'PGSTAR failed in reading hydrogen burn data'
     285            0 :          return
     286              :       end if
     287              : 
     288              :       call read_TRho_data(&
     289            0 :          'helium_burn.data', helium_burn_logT, helium_burn_logRho, ierr)
     290            0 :       if (ierr /= 0) then
     291            0 :          write(*, *) 'PGSTAR failed in reading helium burn data'
     292            0 :          return
     293              :       end if
     294              : 
     295              :       call read_TRho_data(&
     296            0 :          'carbon_burn.data', carbon_burn_logT, carbon_burn_logRho, ierr)
     297            0 :       if (ierr /= 0) then
     298            0 :          write(*, *) 'PGSTAR failed in reading carbon burn data'
     299            0 :          return
     300              :       end if
     301              : 
     302              :       call read_TRho_data(&
     303            0 :          'oxygen_burn.data', oxygen_burn_logT, oxygen_burn_logRho, ierr)
     304            0 :       if (ierr /= 0) then
     305            0 :          write(*, *) 'PGSTAR failed in reading oxygen burn data'
     306            0 :          return
     307              :       end if
     308              : 
     309              :       call read_TRho_data(&
     310            0 :          'psi4.data', psi4_logT, psi4_logRho, ierr)
     311            0 :       if (ierr /= 0) then
     312            0 :          write(*, *) 'PGSTAR failed in reading psi4 data'
     313            0 :          return
     314              :       end if
     315              : 
     316              :       call read_TRho_data(&
     317            0 :          'elect.data', elect_data_logT, elect_data_logRho, ierr)
     318            0 :       if (ierr /= 0) then
     319            0 :          write(*, *) 'PGSTAR failed in reading elect data'
     320            0 :          return
     321              :       end if
     322              : 
     323              :       call read_TRho_data(&
     324            0 :          'gamma_4_thirds.data', gamma_4_thirds_logT, gamma_4_thirds_logRho, ierr)
     325            0 :       if (ierr /= 0) then
     326            0 :          write(*, *) 'PGSTAR failed in reading gamma_4_thirds data'
     327            0 :          return
     328              :       end if
     329              : 
     330              :       call read_TRho_data(&
     331            0 :          'kap_rad_cond_eq.data', kap_rad_cond_eq_logT, kap_rad_cond_eq_logRho, ierr)
     332            0 :       if (ierr /= 0) then
     333            0 :          write(*, *) 'PGSTAR failed in reading kap_rad_cond_eq data'
     334            0 :          return
     335              :       end if
     336              : 
     337              :       call read_TRho_data(&
     338            0 :          'opal_clip.data', opal_clip_logT, opal_clip_logRho, ierr)
     339            0 :       if (ierr /= 0) then
     340            0 :          write(*, *) 'PGSTAR failed in reading opal_clip data'
     341            0 :          return
     342              :       end if
     343              : 
     344              :       call read_TRho_data(&
     345            0 :          'scvh_clip.data', scvh_clip_logT, scvh_clip_logRho, ierr)
     346            0 :       if (ierr /= 0) then
     347            0 :          write(*, *) 'PGSTAR failed in reading scvh_clip data'
     348            0 :          return
     349              :       end if
     350              : 
     351              :    end subroutine read_support_info
     352              : 
     353            0 :    subroutine read_TRho_data(fname, logTs, logRhos, ierr)
     354              :       use utils_lib
     355              :       character (len = *), intent(in) :: fname
     356              :       real, dimension(:), allocatable :: logTs, logRhos  ! will allocate
     357              :       integer, intent(out) :: ierr
     358              : 
     359              :       character (len = strlen) :: filename
     360            0 :       real :: logT, logRho
     361              :       integer :: iounit, i, sz, cnt
     362              : 
     363            0 :       filename = trim(mesa_data_dir) // '/star_data/plot_info/' // trim(fname)
     364              : 
     365            0 :       open(newunit = iounit, file = trim(filename), status = 'old', action = 'read', iostat = ierr)
     366            0 :       if (ierr/=0) then
     367            0 :          write(*, *) 'failed to open ' // trim(filename)
     368            0 :          call done
     369            0 :          return
     370              :       end if
     371              : 
     372              :       sz = 0
     373            0 :       do
     374            0 :          read(iounit, *, iostat = ierr)
     375            0 :          if(ierr/=0) exit
     376            0 :          sz = sz + 1
     377              :       end do
     378              : 
     379            0 :       rewind(iounit)
     380              : 
     381            0 :       allocate(logTs(sz), logRhos(sz))
     382              : 
     383            0 :       cnt = 0
     384            0 :       do i = 1, sz
     385            0 :          read(iounit, *, iostat = ierr) logRho, logT
     386            0 :          if (ierr /= 0) then
     387            0 :             ierr = 0; exit
     388              :          end if
     389            0 :          logRhos(i) = logRho
     390            0 :          logTs(i) = logT
     391            0 :          cnt = i
     392              :       end do
     393              : 
     394            0 :       call done
     395              : 
     396              : 
     397              :    contains
     398              : 
     399              : 
     400            0 :       subroutine done
     401            0 :          close(iounit)
     402            0 :       end subroutine done
     403              : 
     404              :    end subroutine read_TRho_data
     405              : 
     406              : 
     407            0 :    integer function write_info_line_str(cnt, ypos, xpos0, dxpos, str)
     408              :       integer, intent(in) :: cnt
     409              :       real, intent(in) :: ypos, xpos0, dxpos
     410              :       character (len = *), intent(in) :: str
     411              :       real :: xpos
     412            0 :       xpos = cnt * dxpos + xpos0
     413            0 :       call pgptxt(xpos, ypos, 0.0, 0.5, trim(adjustl(str)))
     414            0 :       write_info_line_str = cnt + 1
     415            0 :    end function write_info_line_str
     416              : 
     417              : 
     418            0 :    integer function write_info_line_int(cnt, ypos, xpos0, dxpos, dxval, label, val)
     419              :       integer, intent(in) :: cnt, val
     420              :       real, intent(in) :: ypos, xpos0, dxpos, dxval
     421              :       character (len = *), intent(in) :: label
     422              : 
     423              :       character (len = 128) :: str
     424              :       real :: xpos
     425              : 
     426            0 :       write(str, '(a)') trim(label)
     427            0 :       xpos = cnt * dxpos + xpos0
     428            0 :       call pgptxt(xpos, ypos, 0.0, 1.0, trim(adjustl(str)))
     429            0 :       write(str, '(i9)') val
     430            0 :       xpos = xpos + dxval
     431            0 :       call pgptxt(xpos, ypos, 0.0, 0.0, trim(adjustl(str)))
     432              : 
     433            0 :       write_info_line_int = cnt + 1
     434            0 :    end function write_info_line_int
     435              : 
     436              : 
     437            0 :    integer function write_info_line_flt(&
     438              :       cnt, ypos, xpos0, dxpos, dxval, label, val)
     439              :       integer, intent(in) :: cnt
     440              :       real, intent(in) :: ypos, xpos0, dxpos, dxval
     441              :       real(dp), intent(in) :: val
     442              :       character (len = *), intent(in) :: label
     443              : 
     444              :       character (len = 128) :: str
     445              :       real :: xpos
     446              :       integer :: ierr
     447              : 
     448            0 :       write_info_line_flt = cnt + 1
     449            0 :       write(str, '(a)')   trim(label)
     450            0 :       xpos = cnt * dxpos + xpos0
     451            0 :       call pgptxt(xpos, ypos, 0.0, 1.0, trim(adjustl(str)))
     452            0 :       ierr = 0
     453            0 :       write(str, '(f12.7)', iostat = ierr) val
     454            0 :       if (ierr /= 0) then
     455            0 :          ierr = 0
     456            0 :          write(str, '(e10.3)', iostat = ierr) val
     457            0 :          if (ierr /= 0) then
     458            0 :             write(*, *) trim(label), val
     459            0 :             write(*, *) 'problem in write_info_line_flt'
     460            0 :             return
     461              :          end if
     462              :       end if
     463            0 :       xpos = xpos + dxval
     464            0 :       call pgptxt(xpos, ypos, 0.0, 0.0, trim(adjustl(str)))
     465              : 
     466            0 :    end function write_info_line_flt
     467              : 
     468              : 
     469            0 :    integer function write_info_line_flt2(cnt, ypos, xpos0, dxpos, dxval, label, val)
     470              :       integer, intent(in) :: cnt
     471              :       real, intent(in) :: ypos, xpos0, dxpos, dxval
     472              :       real(dp), intent(in) :: val
     473              :       character (len = *), intent(in) :: label
     474              : 
     475              :       character (len = 128) :: str
     476              :       real :: xpos
     477              :       integer :: ierr
     478              : 
     479            0 :       write_info_line_flt2 = cnt + 1
     480              : 
     481            0 :       write(str, '(a)')   trim(label)
     482            0 :       xpos = cnt * dxpos + xpos0
     483            0 :       call pgptxt(xpos, ypos, 0.0, 1.0, trim(adjustl(str)))
     484            0 :       ierr = 0
     485            0 :       write(str, '(f12.3)', iostat = ierr) val
     486            0 :       if (ierr /= 0) then
     487            0 :          ierr = 0
     488            0 :          write(str, '(e10.3)', iostat = ierr) val
     489            0 :          if (ierr /= 0) then
     490            0 :             write(*, *) trim(label), val
     491            0 :             write(*, *) 'problem in write_info_line_flt2'
     492            0 :             return
     493              :          end if
     494              :       end if
     495            0 :       xpos = xpos + dxval
     496            0 :       call pgptxt(xpos, ypos, 0.0, 0.0, trim(adjustl(str)))
     497              : 
     498            0 :    end function write_info_line_flt2
     499              : 
     500              : 
     501            0 :    integer function write_info_line_exp(cnt, ypos, xpos0, dxpos, dxval, label, val)
     502              :       integer, intent(in) :: cnt
     503              :       real, intent(in) :: ypos, xpos0, dxpos, dxval
     504              :       real(dp), intent(in) :: val
     505              :       character (len = *), intent(in) :: label
     506              : 
     507              :       character (len = 128) :: str
     508              :       real :: xpos
     509              : 
     510            0 :       write(str, '(a)')   trim(label)
     511            0 :       xpos = cnt * dxpos + xpos0
     512            0 :       call pgptxt(xpos, ypos, 0.0, 1.0, trim(adjustl(str)))
     513            0 :       write(str, '(1pe10.3)') val
     514            0 :       xpos = xpos + dxval
     515            0 :       call pgptxt(xpos, ypos, 0.0, 0.0, trim(adjustl(str)))
     516              : 
     517            0 :       write_info_line_exp = cnt + 1
     518            0 :    end function write_info_line_exp
     519              : 
     520              : 
     521            0 :    integer function count_hist_points(&
     522              :       s, step_min, step_max) result(numpts)
     523              :       type (star_info), pointer :: s
     524              :       integer, intent(in) :: step_min, step_max
     525              :       type (pgstar_hist_node), pointer :: pg
     526              :       include 'formats'
     527            0 :       numpts = 0
     528            0 :       pg => s% pg% pgstar_hist
     529            0 :       do  ! recall that hist list is decreasing by age (and step)
     530            0 :          if (.not. associated(pg)) return
     531            0 :          if (pg% step < step_min) return
     532            0 :          if (pg% step <= step_max .or. step_max <= 0) numpts = numpts + 1
     533            0 :          pg => pg% next
     534              :       end do
     535              :    end function count_hist_points
     536              : 
     537              : 
     538            0 :    logical function get1_hist_yvec(s, step_min, step_max, n, name, vec)
     539              :       use utils_lib, only : integer_dict_lookup
     540              :       type (star_info), pointer :: s
     541              :       integer, intent(in) :: step_min, step_max, n  ! n = count_hist_points
     542              :       character (len = *) :: name
     543              :       real, dimension(:), allocatable :: vec
     544              :       integer :: i, cnt, ierr
     545              :       character (len = 64) :: key_name
     546              :       include 'formats'
     547            0 :       cnt = 0
     548            0 :       ierr = 0
     549            0 :       do i = 1, len(key_name)
     550            0 :          key_name(i:i) = ' '
     551              :       end do
     552            0 :       do i = 1, len_trim(name)
     553            0 :          if (name(i:i) == ' ') then
     554            0 :             cnt = cnt + 1
     555            0 :             key_name(i:i) = '_'
     556              :          else
     557            0 :             key_name(i:i) = name(i:i)
     558              :          end if
     559              :       end do
     560            0 :       call integer_dict_lookup(s% history_names_dict, key_name, i, ierr)
     561            0 :       if (ierr /= 0 .or. i <= 0) then  ! didn't find it
     562              :          get1_hist_yvec = .false.
     563              :          return
     564              :       end if
     565            0 :       call get_hist_points(s, step_min, step_max, n, i, vec, ierr)
     566            0 :       if (ierr /= 0) then  ! didn't get them
     567              :          get1_hist_yvec = .false.
     568              :          return
     569              :       end if
     570              :       get1_hist_yvec = .true.
     571              :    end function get1_hist_yvec
     572              : 
     573              : 
     574            0 :    subroutine set_hist_points_steps(&
     575            0 :       s, step_min, step_max, numpts, vec, ierr)
     576              :       type (star_info), pointer :: s
     577              :       integer, intent(in) :: step_min, step_max, numpts
     578              :       real, intent(out) :: vec(:)
     579              :       integer, intent(out) :: ierr
     580              :       integer :: i
     581              :       type (pgstar_hist_node), pointer :: pg
     582            0 :       ierr = 0
     583            0 :       if (numpts == 0) return
     584            0 :       pg => s% pg% pgstar_hist
     585            0 :       i = numpts
     586            0 :       do  ! recall that hist list is decreasing by age (and step)
     587            0 :          if (.not. associated(pg)) then
     588            0 :             ierr = -1
     589            0 :             return
     590              :          end if
     591            0 :          if (pg% step < step_min) then
     592            0 :             ierr = -1
     593            0 :             return
     594              :          end if
     595            0 :          if (pg% step <= step_max) then
     596            0 :             vec(i) = real(pg% step)
     597            0 :             i = i - 1
     598            0 :             if (i == 0) return
     599              :          end if
     600            0 :          pg => pg% next
     601              :       end do
     602              :    end subroutine set_hist_points_steps
     603              : 
     604              : 
     605            0 :    integer function get_hist_index(s, spec) result(index)
     606              :       type (star_info), pointer :: s
     607              :       integer, intent(in) :: spec
     608              :       integer :: i, num
     609              :       ! note: this doesn't include "extra" columns
     610            0 :       num = size(s% history_column_spec, dim = 1)
     611            0 :       do i = 1, num
     612            0 :          if (s% history_column_spec(i) == spec) then
     613            0 :             index = i
     614            0 :             return
     615              :          end if
     616              :       end do
     617            0 :       index = -1
     618              :    end function get_hist_index
     619              : 
     620              : 
     621            0 :    subroutine get_hist_points(&
     622            0 :       s, step_min, step_max, numpts, index, vec, ierr)
     623              :       type (star_info), pointer :: s
     624              :       integer, intent(in) :: step_min, step_max, numpts, index
     625              :       real, intent(out) :: vec(:)
     626              :       integer, intent(out) :: ierr
     627              :       integer :: i
     628              :       type (pgstar_hist_node), pointer :: pg => null()
     629              :       include 'formats'
     630            0 :       if (numpts == 0) return
     631            0 :       pg => s% pg% pgstar_hist
     632            0 :       i = numpts
     633            0 :       vec = 0
     634            0 :       ierr = 0
     635            0 :       do  ! recall that hist list is decreasing by age (and step)
     636            0 :          if (.not. associated(pg)) return
     637            0 :          if (pg% step < step_min) then
     638              :             ! this will not happen if have correct numpts
     639              :             return
     640              :          end if
     641            0 :          if (pg% step <= step_max .or. step_max <= 0) then
     642            0 :             if (.not. associated(pg% vals)) then
     643              :                !ierr = -1
     644              :                !write(*,6) 'failed in get_hist_points: not associated', &
     645              :                !   s% model_number, index, numpts, step_min, step_max
     646              :                !call mesa_error(__FILE__,__LINE__,'get_hist_points')
     647              :                return
     648              :             end if
     649            0 :             if (size(pg% vals, dim = 1) < index) then
     650              :                !ierr = -1
     651              :                !write(*,7) 'failed in get_hist_points: size < index', &
     652              :                !   s% model_number, size(pg% vals,dim=1), index, numpts, step_min, step_max
     653              :                !call mesa_error(__FILE__,__LINE__,'get_hist_points')
     654              :                return
     655              :             end if
     656            0 :             vec(i) = pg% vals(index)
     657            0 :             i = i - 1
     658            0 :             if (i == 0) return
     659              :          end if
     660            0 :          pg => pg% next
     661              :       end do
     662              :    end subroutine get_hist_points
     663              : 
     664              : 
     665            0 :    logical function find_shock(s, xaxis_id, xshock) result(found_shock)
     666              :       use profile, only : get_profile_val
     667              :       use num_lib, only : find0
     668              :       type (star_info), pointer :: s
     669              :       integer, intent(in) :: xaxis_id
     670              :       real(dp), intent(out) :: xshock
     671              :       integer :: k, nz
     672            0 :       real(dp) :: cs, x00, xp1, ms
     673              :       real(dp), pointer :: v(:) => null()
     674              :       include 'formats'
     675            0 :       nz = s% nz
     676            0 :       if (s% u_flag) then
     677            0 :          v => s% u
     678              :       else
     679            0 :          v => s% v
     680              :       end if
     681              :       ! search in from surface
     682            0 :       do k = 1, nz - 1
     683            0 :          cs = s% csound(k)  ! cell center
     684            0 :          if (v(k + 1) >= cs .and. v(k) < cs) then
     685              :             found_shock = .true.
     686              :             exit
     687              :          end if
     688              :       end do
     689              :       if (.not. found_shock) then
     690              :          ! search out from center
     691              :          do k = nz - 1, 1, -1
     692              :             cs = s% csound(k)  ! cell center
     693              :             if (v(k + 1) >= -cs .and. v(k) < -cs) then
     694              :                found_shock = .true.
     695              :                exit
     696              :             end if
     697              :          end do
     698              :       end if
     699              :       if (found_shock) then
     700            0 :          x00 = get_profile_val(s, xaxis_id, k)
     701            0 :          xp1 = get_profile_val(s, xaxis_id, k + 1)
     702            0 :          cs = s% csound(k)
     703            0 :          ms = find0(0d0, s% dm(k), v(k + 1) - cs, v(k) - cs)
     704            0 :          xshock = xp1 + (x00 - xp1) * ms / s% dm(k)
     705            0 :          if (is_bad(xshock)) then
     706            0 :             write(*, 2) 'xshock nz', nz, xshock
     707            0 :             write(*, 2) 's% dm(k)', k, s% dm(k)
     708            0 :             write(*, 2) 's% csound(k)', k, s% csound(k)
     709            0 :             write(*, 2) 'v(k)', k, v(k)
     710            0 :             write(*, 2) 'v(k+1)', k + 1, v(k + 1)
     711            0 :             write(*, 1) 'ms', ms
     712            0 :             write(*, 1) 'x00', x00
     713            0 :             write(*, 1) 'xp1', xp1
     714            0 :             nullify(v)
     715            0 :             call mesa_error(__FILE__, __LINE__, 'find_shock')
     716              :          end if
     717              :       end if
     718            0 :       nullify(v)
     719            0 :    end function find_shock
     720              : 
     721              : 
     722            0 :    subroutine set_grid_minmax(&
     723            0 :       nz, xvec, xmin, xmax, xleft, xright, xaxis_by, &
     724              :       given_xmin, given_xmax, margin_in, reversed, &
     725              :       grid_min, grid_max, dxmin)
     726              :       integer, intent(in) :: nz
     727              :       real, intent(in), dimension(:) :: xvec
     728              :       real, intent(out) :: xmin, xmax, xleft, xright
     729              :       character (len = *), intent(in) :: xaxis_by
     730              :       real, intent(in) :: given_xmin, given_xmax, margin_in
     731              :       real, intent(in) :: dxmin
     732              :       logical, intent(in) :: reversed
     733              :       integer, intent(out) :: grid_min, grid_max
     734              :       integer :: k
     735            0 :       real :: dx, margin
     736              :       logical :: use_given_xmin, use_given_xmax
     737              : 
     738              :       include 'formats'
     739              : 
     740            0 :       margin = max(0.0, margin_in)
     741              : 
     742              :       ! use given if it isn't = 101
     743            0 :       use_given_xmin = abs(given_xmin + 101.0) > 1e-6
     744            0 :       if (xaxis_by == 'mass' .and. given_xmin < 0 .and. use_given_xmin) then
     745            0 :          xmin = maxval(xvec(1:nz)) + given_xmin
     746            0 :       else if (use_given_xmin) then
     747            0 :          xmin = given_xmin
     748            0 :       else if (xaxis_by == 'logxm' .or. xaxis_by == 'logxq') then
     749            0 :          xmin = minval(xvec(2:nz))
     750              :       else
     751            0 :          xmin = minval(xvec(1:nz))
     752              :       end if
     753              : 
     754            0 :       use_given_xmax = abs(given_xmax + 101.0) > 1e-6
     755            0 :       if (xaxis_by == 'mass' .and. given_xmax < 0 .and. use_given_xmax) then
     756            0 :          xmax = maxval(xvec(1:nz)) + given_xmax
     757            0 :       else if (use_given_xmax) then
     758            0 :          xmax = given_xmax
     759              :       else
     760            0 :          xmax = maxval(xvec(1:nz))
     761              :       end if
     762            0 :       dx = xmax - xmin
     763              : 
     764            0 :       if (.not. use_given_xmin) xmin = xmin - margin * dx
     765            0 :       if (.not. use_given_xmax) xmax = xmax + margin * dx
     766              : 
     767            0 :       dx = xmax - xmin
     768            0 :       if (dx < dxmin) then
     769            0 :          dx = dxmin
     770            0 :          xmax = (xmax + xmin) / 2 + dx / 2
     771            0 :          xmin = xmax - dx
     772              :       end if
     773              : 
     774            0 :       if (xmin == xmax) then
     775            0 :          xmin = xmin - margin / 2
     776            0 :          xmax = xmax + margin / 2
     777              :       end if
     778              : 
     779            0 :       if (reversed) then
     780            0 :          xright = xmin; xleft = xmax
     781              :       else
     782            0 :          xright = xmax; xleft = xmin
     783              :       end if
     784              : 
     785            0 :       if (xvec(1) < xvec(nz)) then  ! increasing xs
     786            0 :          grid_max = nz
     787            0 :          do k = nz - 1, 1, -1  ! in decreasing order
     788            0 :             if (xvec(k) < xmax) then  ! this is the first one < xmax
     789            0 :                grid_max = k + 1
     790            0 :                exit
     791              :             end if
     792              :          end do
     793            0 :          grid_min = 1
     794            0 :          do k = grid_max, 1, -1
     795            0 :             if (xvec(k) <= xmin) then  ! this is the first one <= xmin
     796            0 :                grid_min = k
     797            0 :                exit
     798              :             end if
     799              :          end do
     800              :       else  ! decreasing
     801            0 :          grid_min = 1
     802            0 :          do k = 2, nz  ! in decreasing order
     803            0 :             if (xvec(k) < xmax) then  ! this is the first one < xmax
     804            0 :                grid_min = k - 1
     805            0 :                exit
     806              :             end if
     807              :          end do
     808            0 :          grid_max = nz
     809            0 :          do k = grid_min, nz
     810            0 :             if (xvec(k) <= xmin) then  ! this is the first one <= xmin
     811            0 :                grid_max = k
     812            0 :                exit
     813              :             end if
     814              :          end do
     815              :       end if
     816              : 
     817            0 :    end subroutine set_grid_minmax
     818              : 
     819              : 
     820            0 :    subroutine set_xleft_xright(&
     821            0 :       npts, xvec, given_xmin, given_xmax, xmargin_in, &
     822              :       reversed, dxmin, xleft, xright)
     823              :       integer, intent(in) :: npts
     824              :       real, intent(in), dimension(:) :: xvec
     825              :       real, intent(in) :: given_xmin, given_xmax, xmargin_in
     826              :       logical, intent(in) :: reversed
     827              :       real, intent(in) :: dxmin
     828              :       real, intent(out) :: xleft, xright
     829              :       call set_ytop_ybot(&
     830              :          npts, xvec, given_xmin, given_xmax, -101.0, xmargin_in, &
     831            0 :          reversed, dxmin, xleft, xright)
     832            0 :    end subroutine set_xleft_xright
     833              : 
     834              : 
     835            0 :    subroutine set_ytop_ybot(&
     836            0 :       npts, yvec, given_ymin, given_ymax, given_ycenter, &
     837              :       ymargin_in, reversed, dymin, ybot, ytop)
     838              :       integer, intent(in) :: npts
     839              :       real, intent(in), dimension(:) :: yvec
     840              :       real, intent(in) :: given_ymin, given_ymax, given_ycenter, ymargin_in
     841              :       logical, intent(in) :: reversed
     842              :       real, intent(in) :: dymin
     843              :       real, intent(out) :: ybot, ytop
     844              : 
     845            0 :       real :: dy, ymax, ymin, ymargin
     846              :       logical :: use_given_ymin, use_given_ymax
     847              :       real, parameter :: dymin_min = 1d-34
     848              : 
     849              :       include 'formats'
     850              : 
     851            0 :       ymargin = max(0.0, ymargin_in)
     852              : 
     853            0 :       use_given_ymin = abs(given_ymin + 101.0) > 1e-6
     854            0 :       if (use_given_ymin) then
     855              :          ymin = given_ymin
     856              :       else
     857            0 :          ymin = minval(yvec(1:npts))
     858              :       end if
     859              : 
     860            0 :       use_given_ymax = abs(given_ymax + 101.0) > 1e-6
     861            0 :       if (use_given_ymax) then
     862              :          ymax = given_ymax
     863              :       else
     864            0 :          ymax = maxval(yvec(1:npts))
     865              :       end if
     866            0 :       dy = ymax - ymin
     867              : 
     868            0 :       if (.not. use_given_ymin) ymin = ymin - ymargin * dy
     869            0 :       if (.not. use_given_ymax) ymax = ymax + ymargin * dy
     870              : 
     871              :       if (abs(given_ycenter + 101.0) > 1e-6 .and. &
     872            0 :          ymax > given_ycenter .and. given_ycenter > ymin) then
     873            0 :          dy = 2d0 * max(given_ycenter - ymin, ymax - given_ycenter)
     874            0 :          ymax = given_ycenter + 0.5d0 * dy
     875            0 :          ymin = given_ycenter - 0.5d0 * dy
     876              :       end if
     877              : 
     878            0 :       dy = ymax - ymin
     879            0 :       if (dy == 0.0) then
     880            0 :          ymax = ymax + dy
     881            0 :          ymin = ymin - dy
     882            0 :       else if (dy < max(dymin, dymin_min)) then
     883              :          !dymin_min prevents graphical glitches and segmentation faults when dy is too small
     884            0 :          dy = max(dymin, dymin_min)
     885            0 :          ymax = (ymax + ymin) / 2 + dy / 2
     886            0 :          ymin = ymax - dy
     887              :       end if
     888              : 
     889            0 :       if (ymin == ymax) then
     890            0 :          ymin = ymin - max(1.0, ymargin) / 2
     891            0 :          ymax = ymax + max(1.0, ymargin) / 2
     892              :       end if
     893              : 
     894            0 :       if (ymin == ymax) then  ! round off problems
     895            0 :          dy = 1e-6 * abs(ymax)
     896            0 :          ymin = ymin - dy
     897            0 :          ymax = ymax + dy
     898              :       end if
     899              : 
     900            0 :       if (reversed) then
     901            0 :          ytop = ymin; ybot = ymax
     902              :       else
     903            0 :          ytop = ymax; ybot = ymin
     904              :       end if
     905              : 
     906            0 :    end subroutine set_ytop_ybot
     907              : 
     908              : 
     909            0 :    subroutine do1_pgmtxt(side, disp, coord, fjust, label, ch, lw)
     910              :       character (len = *), intent(in) :: side, label
     911              :       real, intent(in) :: disp, coord, fjust, ch
     912              :       integer, intent(in) :: lw
     913            0 :       real :: sav_ch
     914              :       integer :: sav_lw
     915            0 :       call pgqch(sav_ch)
     916            0 :       call pgqlw(sav_lw)
     917            0 :       call pgslw(lw)
     918            0 :       call pgsch(ch)
     919            0 :       call pgmtxt(side, disp, coord, fjust, label)
     920            0 :       call pgslw(sav_lw)
     921            0 :       call pgsch(sav_ch)
     922            0 :    end subroutine do1_pgmtxt
     923              : 
     924              : 
     925            0 :    subroutine show_annotations(s, show_annotation1, show_annotation2, show_annotation3)
     926              :       type (star_info), pointer :: s
     927              :       logical, intent(in) :: show_annotation1, show_annotation2, show_annotation3
     928            0 :       if (show_annotation1 .and. len_trim(s% pg% annotation1_text) > 0) then
     929            0 :          call pgsci(s% pg% annotation1_ci)
     930            0 :          call pgscf(s% pg% annotation1_cf)
     931              :          call do1_pgmtxt(s% pg% annotation1_side, s% pg% annotation1_disp, &
     932              :             s% pg% annotation1_coord, s% pg% annotation1_fjust, s% pg% annotation1_text, &
     933            0 :             s% pg% annotation1_ch, s% pg% annotation1_lw)
     934              :       end if
     935            0 :       if (show_annotation2 .and. len_trim(s% pg% annotation2_text) > 0) then
     936            0 :          call pgsci(s% pg% annotation2_ci)
     937            0 :          call pgscf(s% pg% annotation2_cf)
     938              :          call do1_pgmtxt(s% pg% annotation2_side, s% pg% annotation2_disp, &
     939              :             s% pg% annotation2_coord, s% pg% annotation2_fjust, s% pg% annotation2_text, &
     940            0 :             s% pg% annotation2_ch, s% pg% annotation2_lw)
     941              :       end if
     942            0 :       if (show_annotation3 .and. len_trim(s% pg% annotation3_text) > 0) then
     943            0 :          call pgsci(s% pg% annotation3_ci)
     944            0 :          call pgscf(s% pg% annotation3_cf)
     945              :          call do1_pgmtxt(s% pg% annotation3_side, s% pg% annotation3_disp, &
     946              :             s% pg% annotation3_coord, s% pg% annotation3_fjust, s% pg% annotation3_text, &
     947            0 :             s% pg% annotation3_ch, s% pg% annotation3_lw)
     948              :       end if
     949            0 :    end subroutine show_annotations
     950              : 
     951            0 :    subroutine set_xaxis_bounds(&
     952              :       s, xaxis_by, win_xmin_in, win_xmax_in, xaxis_reversed, xmargin, &
     953              :       xvec, xmin, xmax, xleft, xright, dx, &
     954              :       grid_min, grid_max, npts, ierr)
     955              :       use profile_getval, only : get_profile_id, get_profile_val
     956              :       type (star_info), pointer :: s
     957              :       character (len = *), intent(in) :: xaxis_by
     958              :       real, intent(in) :: win_xmin_in, win_xmax_in, xmargin
     959              :       logical, intent(in) :: xaxis_reversed
     960              :       real, allocatable, dimension(:) :: xvec
     961              :       real, intent(out) :: xmin, xmax, xleft, xright, dx
     962              :       integer, intent(out) :: grid_min, grid_max, npts
     963              :       integer, intent(out) :: ierr
     964              : 
     965              :       integer :: k, nz, xaxis_id
     966              :       real :: win_xmin, win_xmax
     967              : 
     968              :       include 'formats'
     969              : 
     970            0 :       ierr = 0
     971            0 :       win_xmin = win_xmin_in
     972            0 :       win_xmax = win_xmax_in
     973            0 :       nz = s% nz
     974              : 
     975            0 :       xaxis_id = get_profile_id(s, xaxis_by)
     976            0 :       if (xaxis_id <= 0) then
     977              :          write(*, '(a)') &
     978            0 :             'pgstar inlist problem: bad value for xaxis_by: <' // trim(xaxis_by) // '>'
     979            0 :          ierr = -1
     980              :          return
     981              :       end if
     982            0 :       do k = 1, nz
     983            0 :          xvec(k) = get_profile_val(s, xaxis_id, k)
     984              :       end do
     985              : 
     986              :       call set_grid_minmax(&
     987              :          nz, xvec, xmin, xmax, xleft, xright, xaxis_by, &
     988            0 :          win_xmin, win_xmax, xmargin, xaxis_reversed, grid_min, grid_max, 0.0)
     989            0 :       dx = xmax - xmin
     990            0 :       npts = grid_max - grid_min + 1
     991            0 :       if (npts <= 0) then
     992            0 :          write(*, *) 'invalid x axis bounds for xaxis_by = ' // trim(xaxis_by)
     993            0 :          write(*, 1) 'xmax', xmax
     994            0 :          write(*, 1) 'xmin', xmin
     995            0 :          write(*, 1) 'dx', dx
     996            0 :          write(*, 1) 'xleft', xleft
     997            0 :          write(*, 1) 'xright', xright
     998            0 :          write(*, 1) 'win_xmin', win_xmin
     999            0 :          write(*, 1) 'win_xmax', win_xmax
    1000            0 :          write(*, 1) 'xmargin', xmargin
    1001            0 :          write(*, 2) 'grid_min', grid_min
    1002            0 :          write(*, 2) 'grid_max', grid_max
    1003            0 :          write(*, 2) 'npts', npts
    1004            0 :          write(*, 2) 'nz', nz
    1005            0 :          write(*, 1) 'maxval(xvec(1:nz))', maxval(xvec(1:nz))
    1006            0 :          write(*, 1) 'minval(xvec(1:nz))', minval(xvec(1:nz))
    1007            0 :          ierr = -1
    1008              :       end if
    1009              : 
    1010            0 :    end subroutine set_xaxis_bounds
    1011              : 
    1012              : 
    1013            0 :    subroutine show_xaxis_name(s, name, ierr)
    1014              :       type (star_info), pointer :: s
    1015              :       character (len = *), intent(in) :: name
    1016              :       integer, intent(out) :: ierr
    1017            0 :       ierr = 0
    1018            0 :       if (name == 'mass') then
    1019            0 :          call show_xaxis_label_pgstar(s, 'm/M\d\(2281)')
    1020            0 :       else if (name == 'grid') then
    1021            0 :          call show_xaxis_label_pgstar(s, 'grid')
    1022            0 :       else if (name == 'radius') then
    1023            0 :          call show_xaxis_label_pgstar(s, 'r/R\d\(2281)')
    1024            0 :       else if (name == 'logR') then
    1025            0 :          call show_xaxis_label_pgstar(s, 'log r/R\d\(2281)')
    1026            0 :       else if (name == 'logT') then
    1027            0 :          call show_xaxis_label_pgstar(s, 'log T')
    1028            0 :       else if (name == 'logP') then
    1029            0 :          call show_xaxis_label_pgstar(s, 'log P')
    1030            0 :       else if (name == 'logxq') then
    1031            0 :          if (s% M_center == 0) then
    1032            0 :             call show_xaxis_label_pgstar(s, 'log(1-q) q=fraction of total mass')
    1033              :          else
    1034            0 :             call show_xaxis_label_pgstar(s, 'log(1-q) q=fraction of envelope mass')
    1035              :          end if
    1036            0 :       else if (name == 'logxm') then
    1037            0 :          call show_xaxis_label_pgstar(s, 'log((Mstar-m)/M\d\(2281)\u)')
    1038            0 :       else if (name == 'r_div_R') then
    1039            0 :          call show_xaxis_label_pgstar(s, 'r/R')
    1040            0 :       else if (name == 'log_column_depth') then
    1041            0 :          call show_xaxis_label_pgstar(s, 'log column depth (g cm\u-2\d)')
    1042              :       else
    1043            0 :          call show_xaxis_label_pgstar(s, name)
    1044              :       end if
    1045            0 :    end subroutine show_xaxis_name
    1046              : 
    1047              : 
    1048            0 :    subroutine show_mix_regions_on_xaxis(s, ybot_in, ytop, grid_min, grid_max, xvec)
    1049              :       type (star_info), pointer :: s
    1050              :       real, intent(in) :: ybot_in, ytop
    1051              :       integer, intent(in) :: grid_min, grid_max
    1052              :       real, allocatable, dimension(:) :: xvec
    1053              :       real :: ybot
    1054            0 :       ybot = ybot_in + 0.001 * (ytop - ybot_in)
    1055            0 :       call show_no_mixing_section(s, ybot, grid_min, grid_max, xvec)
    1056            0 :       call show_convective_section(s, ybot, grid_min, grid_max, xvec)
    1057            0 :       call show_leftover_convective_section(s, ybot, grid_min, grid_max, xvec)
    1058            0 :       call show_semiconvective_section(s, ybot, grid_min, grid_max, xvec)
    1059            0 :       call show_thermohaline_section(s, ybot, grid_min, grid_max, xvec)
    1060            0 :       call show_rotation_section(s, ybot, grid_min, grid_max, xvec)
    1061            0 :       call show_overshoot_section(s, ybot, grid_min, grid_max, xvec)
    1062            0 :    end subroutine show_mix_regions_on_xaxis
    1063              : 
    1064              : 
    1065            0 :    subroutine show_no_mixing_section(s, ybot, grid_min, grid_max, xvec)
    1066              :       use pgstar_colors
    1067              :       type (star_info), pointer :: s
    1068              :       real, intent(in) :: ybot
    1069              :       integer, intent(in) :: grid_min, grid_max
    1070              :       real, allocatable, dimension(:) :: xvec
    1071            0 :       call show_mixing_section(s, ybot, grid_min, grid_max, xvec, no_mixing, clr_no_mixing)
    1072            0 :    end subroutine show_no_mixing_section
    1073              : 
    1074              : 
    1075            0 :    subroutine show_convective_section(s, ybot, grid_min, grid_max, xvec)
    1076              :       use pgstar_colors
    1077              :       type (star_info), pointer :: s
    1078              :       real, intent(in) :: ybot
    1079              :       integer, intent(in) :: grid_min, grid_max
    1080              :       real, allocatable, dimension(:) :: xvec
    1081              :       call show_mixing_section(&
    1082            0 :          s, ybot, grid_min, grid_max, xvec, convective_mixing, clr_convection)
    1083            0 :    end subroutine show_convective_section
    1084              : 
    1085              : 
    1086            0 :    subroutine show_leftover_convective_section(s, ybot, grid_min, grid_max, xvec)
    1087              :       use pgstar_colors
    1088              :       type (star_info), pointer :: s
    1089              :       real, intent(in) :: ybot
    1090              :       integer, intent(in) :: grid_min, grid_max
    1091              :       real, allocatable, dimension(:) :: xvec
    1092              :       call show_mixing_section(&
    1093            0 :          s, ybot, grid_min, grid_max, xvec, leftover_convective_mixing, clr_leftover_convection)
    1094            0 :    end subroutine show_leftover_convective_section
    1095              : 
    1096              : 
    1097            0 :    subroutine show_semiconvective_section(s, ybot, grid_min, grid_max, xvec)
    1098              :       use pgstar_colors
    1099              :       type (star_info), pointer :: s
    1100              :       real, intent(in) :: ybot
    1101              :       integer, intent(in) :: grid_min, grid_max
    1102              :       real, allocatable, dimension(:) :: xvec
    1103              :       call show_mixing_section(&
    1104            0 :          s, ybot, grid_min, grid_max, xvec, semiconvective_mixing, clr_semiconvection)
    1105            0 :    end subroutine show_semiconvective_section
    1106              : 
    1107              : 
    1108            0 :    subroutine show_thermohaline_section(s, ybot, grid_min, grid_max, xvec)
    1109              :       use pgstar_colors
    1110              :       type (star_info), pointer :: s
    1111              :       real, intent(in) :: ybot
    1112              :       integer, intent(in) :: grid_min, grid_max
    1113              :       real, allocatable, dimension(:) :: xvec
    1114              :       call show_mixing_section(&
    1115            0 :          s, ybot, grid_min, grid_max, xvec, thermohaline_mixing, clr_thermohaline)
    1116            0 :    end subroutine show_thermohaline_section
    1117              : 
    1118              : 
    1119            0 :    subroutine show_rotation_section(s, ybot, grid_min, grid_max, xvec)
    1120              :       use pgstar_colors
    1121              :       type (star_info), pointer :: s
    1122              :       real, intent(in) :: ybot
    1123              :       integer, intent(in) :: grid_min, grid_max
    1124              :       real, allocatable, dimension(:) :: xvec
    1125              :       call show_mixing_section(&
    1126            0 :          s, ybot, grid_min, grid_max, xvec, rotation_mixing, clr_rotation)
    1127            0 :    end subroutine show_rotation_section
    1128              : 
    1129              : 
    1130            0 :    subroutine show_overshoot_section(s, ybot, grid_min, grid_max, xvec)
    1131              :       use pgstar_colors
    1132              :       type (star_info), pointer :: s
    1133              :       real, intent(in) :: ybot
    1134              :       integer, intent(in) :: grid_min, grid_max
    1135              :       real, allocatable, dimension(:) :: xvec
    1136              :       call show_mixing_section(&
    1137            0 :          s, ybot, grid_min, grid_max, xvec, overshoot_mixing, clr_overshoot)
    1138            0 :    end subroutine show_overshoot_section
    1139              : 
    1140              : 
    1141            0 :    subroutine show_mixing_section(s, ybot, grid_min, grid_max, xvec, mixing_type, clr)
    1142              :       type (star_info), pointer :: s
    1143              :       real, intent(in) :: ybot
    1144              :       real, allocatable, dimension(:) :: xvec
    1145              :       integer, intent(in) :: mixing_type, clr, grid_min, grid_max
    1146              : 
    1147              :       integer :: k, first, last
    1148              :       logical :: inside
    1149              :       include 'formats'
    1150            0 :       inside = (s% mixing_type(grid_min) == mixing_type)
    1151            0 :       first = grid_min
    1152            0 :       call pgsci(clr)
    1153            0 :       do k = grid_min, grid_max  ! 2,s% nz
    1154            0 :          if (.not. inside) then
    1155            0 :             if (s% mixing_type(k) == mixing_type) then  ! starting
    1156            0 :                inside = .true.
    1157            0 :                first = k
    1158              :             end if
    1159              :          else  ! inside
    1160            0 :             if (s% mixing_type(k) /= mixing_type) then  ! ending
    1161            0 :                last = k - 1
    1162            0 :                call pgmove(xvec(first), ybot)
    1163            0 :                call pgdraw(xvec(last), ybot)
    1164            0 :                inside = .false.
    1165              :             end if
    1166              :          end if
    1167              :       end do
    1168            0 :       if (inside) then
    1169            0 :          last = grid_max
    1170            0 :          call pgmove(xvec(first), ybot)
    1171            0 :          call pgdraw(xvec(last), ybot)
    1172              :       end if
    1173            0 :    end subroutine show_mixing_section
    1174              : 
    1175              : 
    1176            0 :    subroutine show_profile_line(&
    1177            0 :       s, xvec, yvec, txt_scale, xmin, xmax, ymin, ymax, &
    1178              :       show_legend, legend_coord, legend_disp1, legend_del_disp, legend_fjust, &
    1179              :       show_mass_pts)
    1180              :       use pgstar_colors
    1181              :       type (star_info), pointer :: s
    1182              :       real, intent(in) :: xvec(:), yvec(:), txt_scale, xmin, xmax, ymin, ymax, &
    1183              :          legend_coord, legend_disp1, legend_del_disp, legend_fjust
    1184              :       logical, intent(in) :: show_legend, show_mass_pts
    1185              : 
    1186            0 :       real :: disp
    1187              :       integer :: nz
    1188              :       logical :: has_convection, has_leftover_convection, has_overshoot, &
    1189              :          has_semiconvection, has_thermohaline, has_rotation
    1190              : 
    1191              :       include 'formats'
    1192              : 
    1193            0 :       call pgsave
    1194              : 
    1195            0 :       nz = s% nz
    1196            0 :       call pgsch(s% pg% TRho_Profile_legend_txt_scale * txt_scale)
    1197              : 
    1198            0 :       call pgsci(clr_Gold)
    1199            0 :       call pgslw(14)
    1200            0 :       call do_show_eps_nuc_section(1d0)
    1201            0 :       call pgslw(1)
    1202            0 :       disp = legend_disp1 + 2 * legend_del_disp
    1203            0 :       if (show_legend) &
    1204            0 :          call pgmtxt('T', disp, legend_coord, legend_fjust, '> 1 erg g\u-1\d s\u-1\d')
    1205              : 
    1206            0 :       call pgsci(clr_Coral)
    1207            0 :       call pgslw(18)
    1208            0 :       call do_show_eps_nuc_section(1d3)
    1209            0 :       call pgslw(1)
    1210            0 :       disp = legend_disp1 + legend_del_disp
    1211            0 :       if (show_legend) &
    1212            0 :          call pgmtxt('T', disp, legend_coord, legend_fjust, '> 1000 erg g\u-1\d s\u-1\d')
    1213              : 
    1214            0 :       call pgsci(clr_Crimson)
    1215            0 :       call pgslw(20)
    1216            0 :       call do_show_eps_nuc_section(1d7)
    1217            0 :       call pgslw(1)
    1218            0 :       disp = legend_disp1
    1219            0 :       if (show_legend) &
    1220            0 :          call pgmtxt('T', disp, legend_coord, legend_fjust, '> 10\u7\d erg g\u-1\d s\u-1\d')
    1221              : 
    1222            0 :       disp = legend_disp1 + 2 * legend_del_disp
    1223              : 
    1224            0 :       call pgsci(clr_no_mixing)
    1225            0 :       call pgslw(10)
    1226            0 :       call pgline(nz, xvec, yvec)
    1227              :       has_convection = do_show_convective_section()
    1228              :       has_leftover_convection = do_show_leftover_convective_section()
    1229              :       has_overshoot = do_show_overshoot_section()
    1230              :       has_semiconvection = do_show_semiconvective_section()
    1231              :       has_thermohaline = do_show_thermohaline_section()
    1232            0 :       if (s% rotation_flag) then
    1233              :          has_rotation = do_show_rotation_section()
    1234              :       else
    1235              :          has_rotation = .false.
    1236              :       end if
    1237            0 :       call pgslw(1)
    1238            0 :       if (show_legend) then
    1239            0 :          call pgslw(1)
    1240            0 :          disp = disp + legend_del_disp
    1241            0 :          call show_legend_text(clr_no_mixing, 'no mixing')
    1242            0 :          if (s% rotation_flag) then
    1243            0 :             disp = disp + legend_del_disp
    1244            0 :             call show_legend_text(clr_rotation, 'rotation')
    1245              :          end if
    1246            0 :          disp = disp + legend_del_disp
    1247            0 :          call show_legend_text(clr_convection, 'convection')
    1248            0 :          disp = disp + legend_del_disp
    1249            0 :          call show_legend_text(clr_overshoot, 'overshoot')
    1250            0 :          disp = disp + legend_del_disp
    1251            0 :          call show_legend_text(clr_semiconvection, 'semiconvection')
    1252            0 :          disp = disp + legend_del_disp
    1253            0 :          call show_legend_text(clr_thermohaline, 'thermohaline')
    1254            0 :          if(s% pg% show_TRho_accretion_mesh_borders) then
    1255            0 :             disp = disp + legend_del_disp
    1256            0 :             call show_legend_text(clr_RoyalPurple, 'Lagrangian Outer Border')
    1257            0 :             disp = disp + legend_del_disp
    1258            0 :             call show_legend_text(clr_RoyalBlue, 'Homologous Inner Boundary')
    1259            0 :             disp = disp + legend_del_disp
    1260            0 :             call show_legend_text(clr_Tan, 'Mass Added This Step')
    1261              :          end if
    1262            0 :          call pgslw(10)
    1263              :       end if
    1264              : 
    1265            0 :       if (show_mass_pts) &
    1266            0 :          call show_mass_points(s, xvec, yvec, txt_scale, xmin, xmax, ymin, ymax)
    1267              : 
    1268            0 :       call pgunsa
    1269              : 
    1270              : 
    1271              :    contains
    1272              : 
    1273            0 :       subroutine show_legend_text(clr, txt)
    1274              :          integer, intent(in) :: clr
    1275              :          character (len = *), intent(in) :: txt
    1276            0 :          call pgsci(clr)
    1277            0 :          call pgmtxt('T', disp, legend_coord, legend_fjust, txt)
    1278            0 :       end subroutine show_legend_text
    1279              : 
    1280              : 
    1281            0 :       subroutine do_show_eps_nuc_section(eps)
    1282              :          real(dp), intent(in) :: eps
    1283              :          integer :: k, first, last
    1284              :          logical :: inside
    1285            0 :          inside = (s% eps_nuc(1) > eps)
    1286              :          if (inside) first = 1
    1287            0 :          do k = 2, s% nz
    1288            0 :             if (.not. inside) then
    1289            0 :                if (s% eps_nuc(k) > eps) then  ! starting
    1290            0 :                   inside = .true.
    1291            0 :                   first = k
    1292              :                end if
    1293              :             else  ! inside
    1294            0 :                if (s% eps_nuc(k) <= eps) then  ! ending
    1295            0 :                   last = k - 1
    1296            0 :                   call pgline(k - first, xvec(first:last), yvec(first:last))
    1297            0 :                   inside = .false.
    1298              :                end if
    1299              :             end if
    1300              :          end do
    1301            0 :          if (inside) then
    1302            0 :             last = nz
    1303            0 :             call pgline(k - first, xvec(first:last), yvec(first:last))
    1304              :          end if
    1305            0 :       end subroutine do_show_eps_nuc_section
    1306              : 
    1307              : 
    1308            0 :       logical function do_show_convective_section()
    1309            0 :          do_show_convective_section = do_show_mixing_section(convective_mixing, clr_convection)
    1310              :       end function do_show_convective_section
    1311              : 
    1312              : 
    1313            0 :       logical function do_show_leftover_convective_section()
    1314            0 :          do_show_leftover_convective_section = do_show_mixing_section(leftover_convective_mixing, clr_leftover_convection)
    1315              :       end function do_show_leftover_convective_section
    1316              : 
    1317              : 
    1318            0 :       logical function do_show_semiconvective_section()
    1319            0 :          do_show_semiconvective_section = do_show_mixing_section(semiconvective_mixing, clr_semiconvection)
    1320              :       end function do_show_semiconvective_section
    1321              : 
    1322              : 
    1323            0 :       logical function do_show_thermohaline_section()
    1324            0 :          do_show_thermohaline_section = do_show_mixing_section(thermohaline_mixing, clr_thermohaline)
    1325              :       end function do_show_thermohaline_section
    1326              : 
    1327              : 
    1328            0 :       logical function do_show_rotation_section()
    1329            0 :          do_show_rotation_section = do_show_mixing_section(rotation_mixing, clr_rotation)
    1330              :       end function do_show_rotation_section
    1331              : 
    1332              : 
    1333            0 :       logical function do_show_overshoot_section()
    1334            0 :          do_show_overshoot_section = do_show_mixing_section(overshoot_mixing, clr_overshoot)
    1335              :       end function do_show_overshoot_section
    1336              : 
    1337              : 
    1338            0 :       logical function do_show_mixing_section(mixing_type, clr)
    1339              :          integer, intent(in) :: mixing_type, clr
    1340              :          integer :: k, first, last
    1341              :          logical :: inside
    1342              :          include 'formats'
    1343            0 :          call pgsave
    1344            0 :          call pgsci(clr)
    1345            0 :          inside = (s% mixing_type(1) == mixing_type)
    1346              :          if (inside) first = 1
    1347            0 :          do_show_mixing_section = .false.
    1348            0 :          do k = 2, s% nz
    1349            0 :             if (.not. inside) then
    1350            0 :                if (s% mixing_type(k) == mixing_type) then  ! starting
    1351            0 :                   inside = .true.
    1352            0 :                   first = k
    1353              :                end if
    1354              :             else  ! inside
    1355            0 :                if (s% mixing_type(k) /= mixing_type) then  ! ending
    1356            0 :                   last = k - 1
    1357            0 :                   call pgline(k - first, xvec(first:last), yvec(first:last))
    1358            0 :                   do_show_mixing_section = .true.
    1359            0 :                   inside = .false.
    1360              :                end if
    1361              :             end if
    1362              :          end do
    1363            0 :          if (inside) then
    1364            0 :             last = nz
    1365            0 :             call pgline(k - first, xvec(first:last), yvec(first:last))
    1366            0 :             do_show_mixing_section = .true.
    1367              :          end if
    1368            0 :          call pgunsa
    1369            0 :       end function do_show_mixing_section
    1370              : 
    1371              : 
    1372              :    end subroutine show_profile_line
    1373              : 
    1374              : 
    1375            0 :    subroutine show_mass_points(s, xvec, yvec, txt_scale, xmin, xmax, ymin, ymax)
    1376              :       type (star_info), pointer :: s
    1377              :       real, intent(in) :: xvec(:), yvec(:), txt_scale, xmin, xmax, ymin, ymax
    1378              :       integer :: i
    1379            0 :       do i = 1, s% pg% num_profile_mass_points
    1380              :          call show_mass_point(&
    1381              :             s, xvec, yvec, txt_scale, xmin, xmax, ymin, ymax, &
    1382              :             s% pg% profile_mass_point_q(i), &
    1383              :             s% pg% profile_mass_point_color_index(i), &
    1384              :             s% pg% profile_mass_point_symbol(i), &
    1385              :             s% pg% profile_mass_point_symbol_scale(i), &
    1386              :             s% pg% profile_mass_point_str(i), &
    1387              :             s% pg% profile_mass_point_str_clr(i), &
    1388            0 :             s% pg% profile_mass_point_str_scale(i))
    1389              :       end do
    1390            0 :    end subroutine show_mass_points
    1391              : 
    1392              : 
    1393            0 :    subroutine show_mass_point(&
    1394            0 :       s, xvec, yvec, txt_scale, xmin, xmax, ymin, ymax, &
    1395              :       q_in, clr_index, symbol, symbol_scale, str, str_clr, str_scale)
    1396              :       type (star_info), pointer :: s
    1397              :       real, intent(in) :: xvec(:), yvec(:), txt_scale, q_in, &
    1398              :          xmin, xmax, ymin, ymax, symbol_scale, str_scale
    1399              :       integer, intent(in) :: clr_index, symbol, str_clr
    1400              :       character (len = *), intent(in) :: str
    1401            0 :       real :: q, q0, q1, x, y, dy
    1402              :       integer :: nz, i, j, k
    1403              :       include 'formats'
    1404            0 :       q = max(0.0, min(1.0, q_in))
    1405            0 :       nz = s% nz
    1406            0 :       i = nz
    1407            0 :       dy = ymax - ymin
    1408            0 :       do k = 1, s% nz - 1
    1409            0 :          if (s% q(k) >= q .and. q > s% q(k + 1)) then
    1410              :             i = k; exit
    1411              :          end if
    1412              :       end do
    1413            0 :       j = i + 1
    1414            0 :       if (j >= nz) j = i
    1415            0 :       q0 = s% q(i)
    1416            0 :       q1 = s% q(j)
    1417            0 :       if ((q0 - q) * (q - q1) < 0) then
    1418            0 :          j = i - 1
    1419            0 :          q1 = s% q(j)
    1420              :       end if
    1421            0 :       x = find0(xvec(i), q0 - q, xvec(j), q1 - q)
    1422            0 :       if (x > xmax .or. x < xmin) return
    1423            0 :       y = find0(yvec(i), q0 - q, yvec(j), q1 - q)
    1424            0 :       if (y > ymax .or. y < ymin) return
    1425            0 :       call pgsave
    1426            0 :       call pgscf(1)
    1427            0 :       call pgslw(1)
    1428            0 :       call pgsci(clr_index)
    1429            0 :       call pgsch(symbol_scale * txt_scale)
    1430            0 :       call pgpt(1, x, y, symbol)
    1431            0 :       call pgsci(str_clr)
    1432            0 :       call pgsch(str_scale * txt_scale)
    1433            0 :       call pgptxt(x, y - 0.015 * dy, 0.0, 0.0, trim(str))
    1434            0 :       call pgunsa
    1435              :    end subroutine show_mass_point
    1436              : 
    1437              : 
    1438            0 :    real function find0(xx1, yy1, xx2, yy2)
    1439              :       real :: xx1, yy1, xx2, yy2
    1440            0 :       real :: a, b, xz
    1441              :       ! returns x where y is 0 on line connecting the points (xx1,yy1) and (xx2,yy2)
    1442            0 :       a = (xx1 * yy2) - (xx2 * yy1)
    1443            0 :       b = yy2 - yy1
    1444            0 :       if ((abs(a) >= abs(b) * 1e30) .and. ((yy1 >= 0 .and. yy2 <= 0) &
    1445              :          .or. (yy1 <= 0 .and. yy2 > 0))) then
    1446            0 :          xz = 0.5 * (xx1 + xx2)
    1447              :       else
    1448            0 :          xz = a / b
    1449              :       end if
    1450            0 :       find0 = xz
    1451            0 :    end function find0
    1452              : 
    1453              : 
    1454            0 :    subroutine show_box_pgstar(s, str1, str2)
    1455              :       type (star_info), pointer :: s
    1456              :       character (len = *), intent(in) :: str1, str2
    1457            0 :       real :: ch
    1458              :       integer :: lw
    1459            0 :       call pgqch(ch)
    1460            0 :       call pgqlw(lw)
    1461            0 :       call pgsch(s% pg% pgstar_num_scale * ch)
    1462            0 :       call pgslw(s% pg% pgstar_box_lw)
    1463            0 :       call pgbox(str1, 0.0, 0, str2, 0.0, 0)
    1464            0 :       call pgsch(ch)
    1465            0 :       call pgslw(lw)
    1466            0 :    end subroutine show_box_pgstar
    1467              : 
    1468              : 
    1469            0 :    subroutine show_grid_title_pgstar(s, title, pad)
    1470              :       type (star_info), pointer :: s
    1471              :       character (len = *), intent(in) :: title
    1472              :       real, intent(in) :: pad
    1473              :       optional pad
    1474            0 :       real :: ch, disp
    1475            0 :       if (.not. s% pg% pgstar_grid_show_title) return
    1476            0 :       if (len_trim(title) == 0) return
    1477            0 :       call pgqch(ch)
    1478            0 :       disp = s% pg% pgstar_grid_title_disp
    1479            0 :       if (present(pad)) disp = disp + pad
    1480              :       call do1_pgmtxt('T', disp, &
    1481              :          s% pg% pgstar_grid_title_coord, s% pg% pgstar_grid_title_fjust, title, &
    1482            0 :          s% pg% pgstar_grid_title_scale * ch, s% pg% pgstar_grid_title_lw)
    1483              :    end subroutine show_grid_title_pgstar
    1484              : 
    1485              : 
    1486            0 :    subroutine show_title_pgstar(s, title, pad)
    1487              :       type (star_info), pointer :: s
    1488              :       character (len = *), intent(in) :: title
    1489              :       real, intent(in) :: pad
    1490              :       optional pad
    1491            0 :       real :: ch, disp
    1492            0 :       if (.not. s% pg% pgstar_show_title) return
    1493            0 :       if (len_trim(title) == 0) return
    1494            0 :       call pgqch(ch)
    1495            0 :       disp = s% pg% pgstar_title_disp
    1496            0 :       if (present(pad)) disp = disp + pad
    1497              :       call do1_pgmtxt('T', disp, &
    1498              :          s% pg% pgstar_title_coord, s% pg% pgstar_title_fjust, title, &
    1499            0 :          s% pg% pgstar_title_scale * ch, s% pg% pgstar_title_lw)
    1500              :    end subroutine show_title_pgstar
    1501              : 
    1502              : 
    1503            0 :    subroutine show_title_label_pgmtxt_pgstar(&
    1504              :       s, coord, fjust, label, pad)
    1505              :       type (star_info), pointer :: s
    1506              :       character (len = *), intent(in) :: label
    1507              :       real, intent(in) :: pad, coord, fjust
    1508              :       optional pad
    1509              :       real :: disp
    1510            0 :       disp = s% pg% pgstar_title_disp
    1511            0 :       if (present(pad)) disp = disp + pad
    1512            0 :       call pgmtxt('T', disp, coord, fjust, label)
    1513            0 :    end subroutine show_title_label_pgmtxt_pgstar
    1514              : 
    1515              : 
    1516            0 :    subroutine show_xaxis_label_pgstar(s, label, pad)
    1517              :       type (star_info), pointer :: s
    1518              :       character (len = *), intent(in) :: label
    1519              :       real, intent(in) :: pad
    1520              :       optional pad
    1521            0 :       real :: ch, disp
    1522            0 :       call pgqch(ch)
    1523            0 :       disp = s% pg% pgstar_xaxis_label_disp
    1524            0 :       if (present(pad)) disp = disp + pad
    1525              :       call do1_pgmtxt('B', disp, 0.5, 0.5, label, &
    1526            0 :          s% pg% pgstar_xaxis_label_scale * ch, s% pg% pgstar_xaxis_label_lw)
    1527            0 :    end subroutine show_xaxis_label_pgstar
    1528              : 
    1529              : 
    1530            0 :    subroutine show_xaxis_label_pgmtxt_pgstar(&
    1531              :       s, coord, fjust, label, pad)
    1532              :       type (star_info), pointer :: s
    1533              :       character (len = *), intent(in) :: label
    1534              :       real, intent(in) :: pad, coord, fjust
    1535              :       optional pad
    1536              :       real :: disp
    1537            0 :       disp = s% pg% pgstar_xaxis_label_disp
    1538            0 :       if (present(pad)) disp = disp + pad
    1539            0 :       call pgmtxt('B', disp, coord, fjust, label)
    1540            0 :    end subroutine show_xaxis_label_pgmtxt_pgstar
    1541              : 
    1542              : 
    1543            0 :    subroutine show_left_yaxis_label_pgstar(s, label, pad)
    1544              :       type (star_info), pointer :: s
    1545              :       character (len = *), intent(in) :: label
    1546              :       real, intent(in) :: pad
    1547              :       optional pad
    1548            0 :       real :: ch, disp
    1549            0 :       call pgqch(ch)
    1550            0 :       disp = s% pg% pgstar_left_yaxis_label_disp
    1551            0 :       if (present(pad)) disp = disp + pad
    1552              :       call do1_pgmtxt('L', disp, 0.5, 0.5, label, &
    1553            0 :          s% pg% pgstar_left_yaxis_label_scale * ch, s% pg% pgstar_left_yaxis_label_lw)
    1554            0 :    end subroutine show_left_yaxis_label_pgstar
    1555              : 
    1556              : 
    1557            0 :    subroutine show_right_yaxis_label_pgstar(s, label, pad)
    1558              :       type (star_info), pointer :: s
    1559              :       character (len = *), intent(in) :: label
    1560              :       real, intent(in) :: pad
    1561              :       optional pad
    1562            0 :       real :: ch, disp
    1563            0 :       call pgqch(ch)
    1564            0 :       disp = s% pg% pgstar_right_yaxis_label_disp
    1565            0 :       if (present(pad)) disp = disp + pad
    1566              :       call do1_pgmtxt('R', disp, 0.5, 0.5, label, &
    1567            0 :          s% pg% pgstar_right_yaxis_label_scale * ch, s% pg% pgstar_right_yaxis_label_lw)
    1568            0 :    end subroutine show_right_yaxis_label_pgstar
    1569              : 
    1570              : 
    1571            0 :    subroutine show_left_yaxis_label_pgmtxt_pgstar(&
    1572              :       s, coord, fjust, label, pad)
    1573              :       type (star_info), pointer :: s
    1574              :       character (len = *), intent(in) :: label
    1575              :       real, intent(in) :: pad, coord, fjust
    1576              :       optional pad
    1577            0 :       real :: ch, disp
    1578            0 :       call pgqch(ch)
    1579            0 :       call pgsch(1.1 * ch)
    1580            0 :       disp = s% pg% pgstar_left_yaxis_label_disp
    1581            0 :       if (present(pad)) disp = disp + pad
    1582            0 :       call pgmtxt('L', disp, coord, fjust, label)
    1583            0 :       call pgsch(ch)
    1584            0 :    end subroutine show_left_yaxis_label_pgmtxt_pgstar
    1585              : 
    1586              : 
    1587            0 :    subroutine show_right_yaxis_label_pgmtxt_pgstar(&
    1588              :       s, coord, fjust, label, pad)
    1589              :       type (star_info), pointer :: s
    1590              :       character (len = *), intent(in) :: label
    1591              :       real, intent(in) :: pad, coord, fjust
    1592              :       optional pad
    1593            0 :       real :: ch, disp
    1594            0 :       call pgqch(ch)
    1595            0 :       call pgsch(1.1 * ch)
    1596            0 :       disp = s% pg% pgstar_right_yaxis_label_disp
    1597            0 :       if (present(pad)) disp = disp + pad
    1598            0 :       call pgmtxt('R', disp, coord, fjust, label)
    1599            0 :       call pgsch(ch)
    1600            0 :    end subroutine show_right_yaxis_label_pgmtxt_pgstar
    1601              : 
    1602              : 
    1603            0 :    subroutine show_model_number_pgstar(s)
    1604              :       type (star_info), pointer :: s
    1605              :       character (len = 32) :: str
    1606            0 :       real :: ch
    1607            0 :       if (.not. s% pg% pgstar_show_model_number) return
    1608            0 :       write(str, '(i9)') s% model_number
    1609            0 :       str = 'model ' // trim(adjustl(str))
    1610            0 :       call pgqch(ch)
    1611              :       call do1_pgmtxt('T', &
    1612              :          s% pg% pgstar_model_disp, s% pg% pgstar_model_coord, &
    1613              :          s% pg% pgstar_model_fjust, str, &
    1614            0 :          s% pg% pgstar_model_scale * ch, s% pg% pgstar_model_lw)
    1615              :    end subroutine show_model_number_pgstar
    1616              : 
    1617              : 
    1618            0 :    subroutine show_age_pgstar(s)
    1619              :       type (star_info), pointer :: s
    1620              :       character (len = 32) :: age_str, units_str
    1621              :       real(dp) :: age
    1622            0 :       real :: ch
    1623              :       integer :: len, i, j, iE
    1624            0 :       if (.not. s% pg% pgstar_show_age) return
    1625            0 :       age = s% star_age
    1626            0 :       if (s% pg% pgstar_show_age_in_seconds) then
    1627            0 :          age = age * secyer
    1628            0 :          units_str = 'secs'
    1629            0 :       else if (s% pg% pgstar_show_age_in_minutes) then
    1630            0 :          age = age * secyer / 60
    1631            0 :          units_str = 'mins'
    1632            0 :       else if (s% pg% pgstar_show_age_in_hours) then
    1633            0 :          age = age * secyer / (60 * 60)
    1634            0 :          units_str = 'hrs'
    1635            0 :       else if (s% pg% pgstar_show_age_in_days) then
    1636            0 :          age = age * secyer / secday
    1637            0 :          units_str = 'days'
    1638            0 :       else if (s% pg% pgstar_show_age_in_years) then
    1639              :          !age = age
    1640            0 :          units_str = 'yrs'
    1641            0 :       else if (s% pg% pgstar_show_log_age_in_years) then
    1642            0 :          age = log10(max(1d-99, age))
    1643            0 :          units_str = 'log yrs'
    1644            0 :       else if (age * secyer < 60) then
    1645            0 :          age = age * secyer
    1646            0 :          units_str = 'secs'
    1647            0 :       else if (age * secyer < 60 * 60) then
    1648            0 :          age = age * secyer / 60
    1649            0 :          units_str = 'mins'
    1650            0 :       else if (age * secyer < secday) then
    1651            0 :          age = age * secyer / (60 * 60)
    1652            0 :          units_str = 'hrs'
    1653            0 :       else if (age * secyer < secday * 500) then
    1654            0 :          age = age * secyer / secday
    1655            0 :          units_str = 'days'
    1656              :       else
    1657              :          !age = age
    1658            0 :          units_str = 'yrs'
    1659              :       end if
    1660            0 :       if (abs(age) > 1e-3 .and. abs(age) < 1e3) then
    1661            0 :          write(age_str, '(f14.6)') age
    1662              :       else
    1663            0 :          write(age_str, '(1pe14.6)') age
    1664            0 :          len = len_trim(age_str)
    1665            0 :          iE = 0
    1666            0 :          do i = 1, len
    1667            0 :             if (age_str(i:i) == 'E') then
    1668            0 :                iE = i
    1669            0 :                age_str(i:i) = 'e'
    1670            0 :                exit
    1671              :             end if
    1672              :          end do
    1673            0 :          if (iE > 0) then
    1674            0 :             i = iE + 1
    1675            0 :             if (age_str(i:i) == '+') then
    1676            0 :                do j = i, len - 1
    1677            0 :                   age_str(j:j) = age_str(j + 1:j + 1)
    1678              :                end do
    1679            0 :                age_str(len:len) = ' '
    1680            0 :                len = len - 1
    1681              :             else
    1682            0 :                i = i + 1
    1683              :             end if
    1684            0 :             if (age_str(i:i) == '0') then
    1685            0 :                do j = i, len - 1
    1686            0 :                   age_str(j:j) = age_str(j + 1:j + 1)
    1687              :                end do
    1688            0 :                age_str(len:len) = ' '
    1689            0 :                len = len - 1
    1690              :             end if
    1691              :          end if
    1692              :       end if
    1693            0 :       age_str = adjustl(age_str)
    1694            0 :       age_str = 'age ' // trim(age_str) // ' ' // trim(units_str)
    1695            0 :       call pgqch(ch)
    1696              :       call do1_pgmtxt('T', &
    1697              :          s% pg% pgstar_age_disp, s% pg% pgstar_age_coord, &
    1698              :          s% pg% pgstar_age_fjust, age_str, &
    1699            0 :          s% pg% pgstar_age_scale * ch, s% pg% pgstar_age_lw)
    1700              :    end subroutine show_age_pgstar
    1701              : 
    1702              : 
    1703            0 :    logical function read_values_from_file(fname, x_data, y_data, data_len)
    1704              :       character(len = *), intent(in) :: fname
    1705              :       real, allocatable, dimension(:) :: x_data, y_data
    1706              :       integer, intent(out) :: data_len
    1707              :       integer :: iounit, ierr, i
    1708              :       include 'formats'
    1709            0 :       read_values_from_file = .false.
    1710            0 :       ierr = 0
    1711            0 :       open(newunit = iounit, file = trim(fname), action = 'read', status = 'old', iostat = ierr)
    1712            0 :       if (ierr /= 0) then
    1713              :          !write(*, *) 'failed to open ' // trim(fname)
    1714              :          return
    1715              :       end if
    1716            0 :       read(iounit, *, iostat = ierr) data_len
    1717            0 :       if (ierr /= 0) then
    1718            0 :          write(*, *) 'failed to read num points on 1st line ' // trim(fname)
    1719            0 :          return
    1720              :       end if
    1721              :       !write(*,2) trim(fname) // ' data_len', data_len
    1722            0 :       allocate(x_data(data_len), y_data(data_len))
    1723            0 :       do i = 1, data_len
    1724            0 :          read(iounit, *, iostat = ierr) x_data(i), y_data(i)
    1725            0 :          if (ierr /= 0) then
    1726            0 :             write(*, *) 'failed to read data ' // trim(fname)
    1727            0 :             deallocate(x_data, y_data)
    1728            0 :             return
    1729              :          end if
    1730              :       end do
    1731            0 :       close(iounit)
    1732            0 :       read_values_from_file = .true.
    1733            0 :    end function read_values_from_file
    1734              : 
    1735              : 
    1736            0 :    subroutine show_pgstar_decorator(id, use_flag, pgstar_decorator, plot_num, ierr)
    1737              :       logical, intent(in) :: use_flag
    1738            0 :       real :: xmin, xmax, ymin, ymax
    1739              :       integer, intent(in) :: id, plot_num
    1740              :       integer, intent(inout) :: ierr
    1741              :       procedure(pgstar_decorator_interface), pointer :: pgstar_decorator
    1742              : 
    1743            0 :       if(use_flag)then
    1744            0 :          if(associated(pgstar_decorator))then
    1745            0 :             call pgsave
    1746            0 :             call PGQWIN(xmin, xmax, ymin, ymax)
    1747            0 :             call pgstar_decorator(id, xmin, xmax, ymin, ymax, plot_num, ierr)
    1748            0 :             call pgunsa
    1749            0 :             if(ierr/=0)then
    1750            0 :                write(*, *) "Error in pgstar_decorator"
    1751              :             end if
    1752              :          end if
    1753              :       end if
    1754              : 
    1755            0 :    end subroutine show_pgstar_decorator
    1756              : 
    1757              : end module pgstar_support
    1758              : 
        

Generated by: LCOV version 2.0-1