LCOV - code coverage report
Current view: top level - binary/private - binary_history.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 425 0
Test Date: 2025-10-14 06:41:40 Functions: 0.0 % 20 0

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2022  Bill Paxton, Pablo Marchant, Matthias Fabry
       4              : !                                                          & The MESA Team
       5              : !
       6              : !   This program is free software: you can redistribute it and/or modify
       7              : !   it under the terms of the GNU Lesser General Public License
       8              : !   as published by the Free Software Foundation,
       9              : !   either version 3 of the License, or (at your option) any later version.
      10              : !
      11              : !   This program is distributed in the hope that it will be useful,
      12              : !   but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      14              : !   See the GNU Lesser General Public License for more details.
      15              : !
      16              : !   You should have received a copy of the GNU Lesser General Public License
      17              : !   along with this program. If not, see <https://www.gnu.org/licenses/>.
      18              : !
      19              : ! ***********************************************************************
      20              : 
      21              : module binary_history
      22              : 
      23              :    use const_def, only: dp, pi, lsun, msun, rsun, secyer, secday, two_thirds
      24              :    use math_lib
      25              :    use binary_def
      26              :    use binary_private_def
      27              :    use binary_history_specs
      28              : 
      29              :    implicit none
      30              : 
      31              : contains
      32              : 
      33            0 :    integer function how_many_binary_history_columns(binary_id)
      34              :       integer, intent(in) :: binary_id
      35              :       integer :: numcols, ierr
      36              :       type (binary_info), pointer :: b
      37              : 
      38              :       ierr = 0
      39            0 :       call binary_ptr(binary_id, b, ierr)
      40            0 :       if (ierr /= 0) then
      41            0 :          write(*, *) 'failed in binary_ptr'
      42            0 :          numcols = 0
      43            0 :          return
      44              :       end if
      45              : 
      46            0 :       if (.not. associated(b% binary_history_column_spec)) then
      47              :          numcols = 0
      48              :       else
      49            0 :          numcols = size(b% binary_history_column_spec, dim = 1)
      50              :       end if
      51              : 
      52            0 :       how_many_binary_history_columns = numcols
      53              :    end function how_many_binary_history_columns
      54              : 
      55              : 
      56            0 :    subroutine data_for_binary_history_columns(&
      57            0 :       binary_id, n, names, vals, ierr)
      58              :       integer, intent(in) :: binary_id, n
      59              :       character (len = 80) :: names(n)
      60              :       real(dp) :: vals(n)
      61              :       integer, intent(out) :: ierr
      62              : 
      63              :       type (binary_info), pointer :: b
      64              :       integer :: c, int_val, j
      65              :       logical :: is_int_val
      66            0 :       real(dp) :: val
      67              : 
      68              :       ierr = 0
      69            0 :       call binary_ptr(binary_id, b, ierr)
      70            0 :       if (ierr /= 0) then
      71            0 :          write(*, *) 'failed in binary_ptr'
      72            0 :          return
      73              :       end if
      74              : 
      75            0 :       do j = 1, n
      76            0 :          c = b% binary_history_column_spec(j)
      77            0 :          names(j) = trim(binary_history_column_name(c))
      78              :          call binary_history_getval(&
      79            0 :             b, c, val, int_val, is_int_val, ierr)
      80            0 :          if (ierr /= 0) then
      81            0 :             write(*, *) "Unknown binary_history_columns.list column"
      82            0 :             return
      83              :          end if
      84            0 :          if (is_int_val) then
      85            0 :             vals(j) = int_val
      86              :          else
      87            0 :             vals(j) = val
      88              :          end if
      89              :       end do
      90              :    end subroutine data_for_binary_history_columns
      91              : 
      92            0 :    subroutine write_binary_history_info(b, ierr)
      93              :       type (binary_info), pointer :: b
      94              :       integer, intent(out) :: ierr
      95              :       logical, parameter :: write_flag = .true.
      96              : 
      97            0 :       call do_binary_history_info(b, write_flag, ierr)
      98            0 :    end subroutine write_binary_history_info
      99              : 
     100            0 :    subroutine do_get_data_for_binary_history_columns(b, ierr)
     101              :       type (binary_info), pointer :: b
     102              :       integer, intent(out) :: ierr
     103              :       logical, parameter :: write_flag = .false.
     104              : 
     105            0 :       call do_binary_history_info(b, write_flag, ierr)
     106            0 :    end subroutine do_get_data_for_binary_history_columns
     107              : 
     108            0 :    subroutine do_binary_history_info(b, write_flag, ierr)
     109              :       use utils_lib, only : integer_dict_create_hash, integer_dict_free
     110              :       type (binary_info), pointer :: b
     111              :       logical, intent(in) :: write_flag
     112              :       integer, intent(out) :: ierr
     113              : 
     114              :       character (len = strlen) :: fname, dbl_fmt, int_fmt, txt_fmt
     115              :       integer :: numcols, io, i, col, j, i0, n
     116              : 
     117              :       integer :: num_extra_header_items, num_extra_cols
     118              : 
     119              :       character (len = maxlen_history_column_name), pointer, dimension(:) :: &
     120            0 :          extra_header_item_names, extra_col_names
     121              :       real(dp), pointer, dimension(:) :: &
     122            0 :          extra_header_item_vals, extra_col_vals
     123              : 
     124              :       logical :: binary_history_file_exists
     125              :       character (len = maxlen_history_column_name), pointer :: &
     126            0 :          names(:)  ! (num_history_columns)
     127            0 :       real(dp), pointer :: vals(:)  ! (num_history_columns)
     128            0 :       logical, pointer :: is_int(:)  ! (num_history_columns)
     129              : 
     130              :       include 'formats'
     131              : 
     132            0 :       extra_header_item_names => null()
     133            0 :       extra_header_item_vals => null()
     134              : 
     135            0 :       extra_col_names => null()
     136            0 :       extra_col_vals => null()
     137              : 
     138            0 :       dbl_fmt = b% history_dbl_format
     139            0 :       int_fmt = b% history_int_format
     140            0 :       txt_fmt = b% history_txt_format
     141              : 
     142            0 :       ierr = 0
     143              : 
     144            0 :       if (.not. associated(b% binary_history_column_spec)) then
     145            0 :          numcols = 0
     146              :       else
     147            0 :          numcols = size(b% binary_history_column_spec, dim = 1)
     148              :       end if
     149              : 
     150            0 :       num_extra_cols = b% how_many_extra_binary_history_columns(b% binary_id)
     151            0 :       n = numcols + num_extra_cols
     152              : 
     153            0 :       if (n == 0) then
     154            0 :          write(*, *) 'WARNING: do not have any output specified for binary logs.'
     155            0 :          return
     156              :       end if
     157              : !      write(*, *) " got num of cols"
     158            0 :       if (b% number_of_binary_history_columns < 0) then
     159            0 :          b% number_of_binary_history_columns = n
     160            0 :       else if (b% number_of_binary_history_columns /= n) then
     161            0 :          if (associated(b% binary_history_values)) then
     162            0 :             deallocate(b% binary_history_values)
     163            0 :             nullify(b% binary_history_values)
     164              :          end if
     165            0 :          if (associated(b% binary_history_names)) then
     166            0 :             deallocate(b% binary_history_names)
     167            0 :             nullify(b% binary_history_names)
     168              :          end if
     169            0 :          if (associated(b% binary_history_value_is_integer)) then
     170            0 :             deallocate(b% binary_history_value_is_integer)
     171            0 :             nullify(b% binary_history_value_is_integer)
     172              :          end if
     173            0 :          if (associated(b% binary_history_names_dict)) then
     174            0 :             call integer_dict_free(b% binary_history_names_dict)
     175            0 :             nullify(b% binary_history_names_dict)
     176              :          end if
     177            0 :          b% need_to_set_binary_history_names_etc = .true.
     178            0 :          b% number_of_binary_history_columns = n
     179              :       end if
     180              : 
     181            0 :       if (.not. associated(b% binary_history_values)) then
     182            0 :          allocate(b% binary_history_values(n))
     183            0 :       else if (size(b% binary_history_values, dim = 1) /= n) then
     184            0 :          ierr = -1
     185            0 :          write(*, 3) 'bad size b% binary_history_values', &
     186            0 :             size(b% binary_history_values, dim = 1), n
     187              :       end if
     188            0 :       vals => b% binary_history_values
     189              : 
     190            0 :       if (.not. associated(b% binary_history_names)) then
     191            0 :          allocate(b% binary_history_names(n))
     192            0 :       else if (size(b% binary_history_names, dim = 1) /= n) then
     193            0 :          ierr = -1
     194            0 :          write(*, 3) 'bad size b% binary_history_names', &
     195            0 :             size(b% binary_history_names, dim = 1), n
     196              :       end if
     197              : 
     198            0 :       if (b% need_to_set_binary_history_names_etc) then
     199            0 :          names => b% binary_history_names
     200              :       else
     201            0 :          nullify(names)
     202              :       end if
     203              : 
     204            0 :       if (.not. associated(b% binary_history_value_is_integer)) then
     205            0 :          allocate(b% binary_history_value_is_integer(n))
     206            0 :       else if (size(b% binary_history_value_is_integer, dim = 1) /= n) then
     207            0 :          ierr = -1
     208            0 :          write(*, 2) 'bad size b% binary_history_value_is_integer', &
     209            0 :             size(b% binary_history_value_is_integer, dim = 1), n
     210              :       end if
     211            0 :       if (b% need_to_set_binary_history_names_etc) then
     212            0 :          is_int => b% binary_history_value_is_integer
     213              :       else
     214            0 :          nullify(is_int)
     215              :       end if
     216              : !      write(*, *) " associated arrays"
     217              : 
     218            0 :       nullify(extra_col_names)
     219            0 :       nullify(extra_col_vals)
     220              : 
     221            0 :       if (num_extra_cols > 0) then
     222              :          allocate(&
     223            0 :             extra_col_names(num_extra_cols), extra_col_vals(num_extra_cols), stat = ierr)
     224            0 :          if (ierr /= 0) then
     225            0 :             call dealloc
     226            0 :             return
     227              :          end if
     228            0 :          extra_col_names(1:num_extra_cols) = 'unknown'
     229            0 :          extra_col_vals(1:num_extra_cols) = -1d99
     230              :          call b% data_for_extra_binary_history_columns(&
     231            0 :             b% binary_id, num_extra_cols, extra_col_names, extra_col_vals, ierr)
     232            0 :          if (ierr /= 0) then
     233            0 :             call dealloc
     234            0 :             return
     235              :          end if
     236            0 :          do i = 1, num_extra_cols
     237            0 :             if(trim(extra_col_names(i))=='unknown') then
     238            0 :                write(*, *) "Warning empty history name for extra_binary_history_column ", i
     239              :             end if
     240              :          end do
     241              :       end if
     242              : 
     243              : !      write(*, *) " starting write loop ", write_flag
     244            0 :       i0 = 1
     245            0 :       if (write_flag .and. (open_close_log .or. b% s_donor% model_number == -100)) then
     246            0 :          fname = trim(b% log_directory) // '/' // trim(b% history_name)
     247            0 :          inquire(file = trim(fname), exist = binary_history_file_exists)
     248            0 :          if ((.not. binary_history_file_exists) .or. b% open_new_history_file) then
     249            0 :             ierr = 0
     250            0 :             open(newunit = io, file = trim(fname), action = 'write', iostat = ierr)
     251            0 :             b% open_new_history_file = .false.
     252              :          else
     253            0 :             i0 = 3
     254            0 :             open(newunit = io, file = trim(fname), action = 'write', position = 'append', iostat = ierr)
     255              :          end if
     256            0 :          if (ierr /= 0) then
     257            0 :             write(*, *) 'failed to open ' // trim(fname)
     258            0 :             call dealloc
     259            0 :             return
     260              :          end if
     261              :       end if
     262              : 
     263            0 :       if (write_flag .and. i0 == 1) then  ! write parameters at start of log
     264              : 
     265            0 :          num_extra_header_items = b% how_many_extra_binary_history_header_items(b% binary_id)
     266              : 
     267            0 :          if (num_extra_header_items > 0) then
     268              :             allocate(&
     269              :                extra_header_item_names(num_extra_header_items), &
     270            0 :                extra_header_item_vals(num_extra_header_items), stat = ierr)
     271            0 :             if (ierr /= 0) then
     272            0 :                call dealloc
     273            0 :                return
     274              :             end if
     275            0 :             extra_header_item_names(1:num_extra_header_items) = 'unknown'
     276            0 :             extra_header_item_vals(1:num_extra_header_items) = -1d99
     277              :             call b% data_for_extra_binary_history_header_items(&
     278              :                b% binary_id, num_extra_header_items, &
     279            0 :                extra_header_item_names, extra_header_item_vals, ierr)
     280            0 :             if (ierr /= 0) then
     281            0 :                call dealloc
     282            0 :                return
     283              :             end if
     284            0 :             do i = 1, num_extra_header_items
     285            0 :                if(trim(extra_header_item_names(i))=='unknown') then
     286            0 :                   write(*, *) "Warning empty history name for extra_binary_history_header ", i
     287              :                end if
     288              :             end do
     289              :          end if
     290              : 
     291            0 :          do i = 1, 3
     292            0 :             col = 0
     293            0 :             call write_string(io, col, i, 'version_number', version_number)
     294            0 :             call write_val(io, col, i, 'initial_don_mass', initial_mass(1))
     295            0 :             call write_val(io, col, i, 'initial_acc_mass', initial_mass(2))
     296              :             call write_val(io, col, i, 'initial_period_days', &
     297            0 :                initial_binary_period / (3600 * 24))
     298              : 
     299            0 :             call write_string(io, col, i, 'compiler', compiler_name)
     300            0 :             call write_string(io, col, i, 'build', compiler_version_name)
     301            0 :             call write_string(io, col, i, 'MESA_SDK_version', mesasdk_version_name)
     302            0 :             call write_string(io, col, i, 'date', date)
     303              : 
     304            0 :             do j = 1, num_extra_header_items
     305              :                call write_val(io, col, i, &
     306            0 :                   extra_header_item_names(j), extra_header_item_vals(j))
     307              :             end do
     308              : 
     309            0 :             write(io, *)
     310              :          end do
     311            0 :          write(io, *)
     312              :       end if
     313              : 
     314            0 :       do i = i0, 3  ! add a row to the log
     315            0 :          col = 0
     316              : !         write(*, *) "doing cols pass", i
     317            0 :          do j = 1, numcols
     318            0 :             call do_col(i, j)
     319              :          end do
     320            0 :          do j = 1, num_extra_cols
     321            0 :             call do_extra_col(i, j)
     322              :          end do
     323            0 :          if (write_flag) write(io, *)
     324              :       end do
     325              : !      write (*, *) "cols handled"
     326            0 :       if (open_close_log) close(io)
     327              : 
     328            0 :       call dealloc
     329              : !      write(*, *) "history written"
     330              : 
     331            0 :       b% model_number_of_binary_history_values = b% model_number
     332              : 
     333            0 :       if (b% need_to_set_binary_history_names_etc) then
     334              : !         write(*, *) " creating hash of the history dict"
     335            0 :          call integer_dict_create_hash(b% binary_history_names_dict, ierr)
     336            0 :          if (ierr /= 0) then
     337            0 :             write(*, *) "hash failed"
     338            0 :             return
     339              :          end if
     340              :       end if
     341              : 
     342            0 :       b% need_to_set_binary_history_names_etc = .false.
     343              : 
     344              :    contains
     345              : 
     346              : 
     347            0 :       subroutine dealloc
     348            0 :          if (associated(extra_header_item_names)) deallocate(extra_header_item_names)
     349            0 :          if (associated(extra_header_item_vals)) deallocate(extra_header_item_vals)
     350            0 :          if (associated(extra_col_names)) deallocate(extra_col_names)
     351            0 :          if (associated(extra_col_vals)) deallocate(extra_col_vals)
     352            0 :       end subroutine dealloc
     353              : 
     354              : 
     355            0 :       subroutine do_extra_col(pass, j)
     356              :          integer, intent(in) :: pass, j
     357            0 :          if (pass == 1) then
     358            0 :             if (write_flag) write(io, fmt = int_fmt, advance = 'no') j + numcols
     359            0 :          else if (pass == 2) then
     360            0 :             call do_name(j + numcols, extra_col_names(j))
     361            0 :          else if (pass == 3) then
     362            0 :             call do_val(j + numcols, extra_col_vals(j))
     363              :          end if
     364            0 :       end subroutine do_extra_col
     365              : 
     366              : 
     367            0 :       subroutine do_name(j, col_name)
     368              :          use utils_lib, only: integer_dict_define
     369              :          integer, intent(in) :: j
     370              :          character (len = *), intent(in) :: col_name
     371            0 :          if (write_flag) write(io, fmt = txt_fmt, advance = 'no') trim(col_name)
     372            0 :          if (associated(names)) names(j) = trim(col_name)
     373            0 :          if (b% need_to_set_binary_history_names_etc) then
     374            0 :             call integer_dict_define(b% binary_history_names_dict, col_name, j, ierr)
     375            0 :             if (ierr /= 0) write(*, *) 'failed in dict define ' // trim(col_name)
     376              :          end if
     377              : 
     378            0 :       end subroutine do_name
     379              : 
     380              : 
     381            0 :       subroutine do_col(pass, j)
     382              :          integer, intent(in) :: pass, j
     383            0 :          if (pass == 1) then
     384            0 :             call do_col_pass1
     385            0 :          else if (pass == 2) then
     386            0 :             call do_col_pass2(j)
     387            0 :          else if (pass == 3) then
     388            0 :             call do_col_pass3(b% binary_history_column_spec(j))
     389              :          end if
     390            0 :       end subroutine do_col
     391              : 
     392              : 
     393            0 :       subroutine do_col_pass1  ! write the column number
     394            0 :          col = col + 1
     395            0 :          if (write_flag) write(io, fmt = int_fmt, advance = 'no') col
     396            0 :       end subroutine do_col_pass1
     397              : 
     398              : 
     399            0 :       subroutine do_col_pass2(j)  ! get the column name
     400              :          integer, intent(in) :: j
     401              :          character (len = 100) :: col_name
     402              :          integer :: c
     403            0 :          c = b% binary_history_column_spec(j)
     404            0 :          col_name = trim(binary_history_column_name(c))
     405            0 :          call do_name(j, col_name)
     406            0 :       end subroutine do_col_pass2
     407              : 
     408              : 
     409            0 :       subroutine do_col_pass3(c)  ! get the column value
     410              :          integer, intent(in) :: c
     411              :          integer :: k, int_val
     412              :          logical :: is_int_val
     413              :          real(dp) :: val
     414              :          int_val = 0; val = 0; is_int_val = .false.
     415              :          call binary_history_getval(&
     416            0 :             b, c, val, int_val, is_int_val, ierr)
     417            0 :          if (ierr /= 0) then
     418            0 :             write(*, *) 'missing log info for ' // trim(binary_history_column_name(c)), j, k
     419            0 :             return
     420              :          end if
     421            0 :          if (is_int_val) then
     422            0 :             call do_int_val(j, int_val)
     423              :          else
     424            0 :             call do_val(j, val)
     425              :          end if
     426              :       end subroutine do_col_pass3
     427              : 
     428              : 
     429            0 :       subroutine do_val(j, val)
     430              :          use utils_lib, only : is_bad
     431              :          integer, intent(in) :: j
     432              :          real(dp), intent(in) :: val
     433            0 :          if (write_flag) then
     434            0 :             if (is_bad(val)) then
     435            0 :                write(io, fmt = dbl_fmt, advance = 'no') -1d99
     436              :             else
     437            0 :                write(io, fmt = dbl_fmt, advance = 'no') val
     438              :             end if
     439              :          end if
     440            0 :          if (associated(vals)) vals(j) = val
     441            0 :          if (associated(is_int)) is_int(j) = .false.
     442            0 :       end subroutine do_val
     443              : 
     444              : 
     445            0 :       subroutine do_int_val(j, val)
     446              :          integer, intent(in) :: j
     447              :          integer, intent(in) :: val
     448            0 :          if (write_flag) write(io, fmt = int_fmt, advance = 'no') val
     449            0 :          if (associated(vals)) vals(j) = dble(val)
     450            0 :          if (associated(is_int)) is_int(j) = .true.
     451            0 :       end subroutine do_int_val
     452              : 
     453              : 
     454              :       subroutine write_integer(io, col, pass, name, val)
     455              :          integer, intent(in) :: io, pass
     456              :          integer, intent(inout) :: col
     457              :          character (len = *), intent(in) :: name
     458              :          integer, intent(in) :: val
     459              :          if (pass == 1) then
     460              :             col = col + 1
     461              :             write(io, fmt = int_fmt, advance = 'no') col
     462              :          else if (pass == 2) then
     463              :             write(io, fmt = txt_fmt, advance = 'no') trim(name)
     464              :          else if (pass == 3) then
     465              :             write(io, fmt = int_fmt, advance = 'no') val
     466              :          end if
     467              :       end subroutine write_integer
     468              : 
     469              : 
     470            0 :       subroutine write_val(io, col, pass, name, val)  ! for header items only
     471              :          integer, intent(in) :: io, pass
     472              :          integer, intent(inout) :: col
     473              :          character (len = *), intent(in) :: name
     474              :          real(dp), intent(in) :: val
     475            0 :          if (pass == 1) then
     476            0 :             col = col + 1
     477            0 :             write(io, fmt = int_fmt, advance = 'no') col
     478            0 :          else if (pass == 2) then
     479            0 :             write(io, fmt = txt_fmt, advance = 'no') trim(name)
     480            0 :          else if (pass == 3) then
     481            0 :             write(io, fmt = dbl_fmt, advance = 'no') val
     482              :          end if
     483            0 :       end subroutine write_val
     484              : 
     485              : 
     486            0 :       subroutine write_string(io, col, pass, name, val)  !for header items only
     487              :          integer, intent(in) :: io, pass
     488              :          integer, intent(inout) :: col
     489              :          character(len = *), intent(in) :: name, val
     490              :          character(len = strlen) :: my_val
     491              : 
     492            0 :          my_val = '"' // trim(val) // '"'
     493            0 :          if (pass == 1) then
     494            0 :             col = col + 1
     495            0 :             write(io, fmt = int_fmt, advance = 'no') col
     496            0 :          else if (pass == 2) then
     497            0 :             write(io, fmt = txt_fmt, advance = 'no') trim(name)
     498            0 :          else if (pass == 3) then
     499            0 :             write(io, fmt = txt_fmt, advance = 'no') trim(my_val)
     500              :          end if
     501            0 :       end subroutine write_string
     502              : 
     503              : 
     504              :    end subroutine do_binary_history_info
     505              : 
     506              : 
     507            0 :    subroutine binary_history_getval(b, c, val, int_val, is_int_val, ierr)
     508              :       type (binary_info), pointer :: b
     509              :       integer, intent(in) :: c
     510              :       real(dp), intent(out) :: val
     511              :       integer, intent(out) :: int_val
     512              :       logical, intent(out) :: is_int_val
     513              :       integer, intent(out) :: ierr
     514              : 
     515              :       include 'formats'
     516              : 
     517            0 :       ierr = 0
     518            0 :       is_int_val = .false.
     519            0 :       int_val = 0
     520            0 :       val = 0
     521            0 :       select case(c)
     522              : 
     523              :       case(bh_model_number)
     524            0 :          int_val = b% model_number
     525            0 :          is_int_val = .true.
     526              :       case(bh_age)
     527            0 :          val = b% binary_age
     528              :       case(bh_donor_index)
     529            0 :          int_val = b% d_i
     530            0 :          is_int_val = .true.
     531              :       case(bh_period_days)
     532            0 :          val = b% period / secday
     533              :       case(bh_period_hr)
     534            0 :          val = b% period / (60d0 * 60d0)
     535              :       case(bh_period_minutes)
     536            0 :          val = b% period / 60d0
     537              :       case(bh_lg_separation)
     538            0 :          val = safe_log10(b% separation)
     539              :       case(bh_binary_separation)
     540            0 :          val = b% separation / Rsun
     541              :       case(bh_eccentricity)
     542            0 :          val = b% eccentricity
     543              :       case(bh_star_1_radius)
     544            0 :          val = b% r(1) / Rsun
     545              :       case(bh_star_2_radius)
     546            0 :          val = b% r(2) / Rsun
     547              :       case(bh_rl_1)
     548            0 :          val = b% rl(1) / Rsun
     549              :       case(bh_rl_2)
     550            0 :          val = b% rl(2) / Rsun
     551              :       case(bh_rl_overflow_1)
     552            0 :          val = (b% r(1) - b% rl(1)) / Rsun
     553              :       case(bh_rl_overflow_2)
     554            0 :          val = (b% r(2) - b% rl(2)) / Rsun
     555              :       case(bh_rl_relative_overflow_1)
     556            0 :          val = b% rl_relative_gap(1)
     557              :       case(bh_rl_relative_overflow_2)
     558            0 :          val = b% rl_relative_gap(2)
     559              :       case(bh_P_rot_div_P_orb_1)
     560            0 :          if (b% point_mass_i /= 1) then
     561            0 :             val = 2 * pi / b% s1% omega_avg_surf / b% period
     562              :          else
     563              :             val = 0.0d0
     564              :          end if
     565              :       case(bh_P_rot_div_P_orb_2)
     566            0 :          if (b% point_mass_i /= 2) then
     567            0 :             val = 2 * pi / b% s2% omega_avg_surf / b% period
     568              :          else
     569            0 :             if (.not. b% model_twins_flag) then
     570              :                val = 0.0d0
     571              :             else
     572            0 :                val = 2 * pi / b% s1% omega_avg_surf / b% period
     573              :             end if
     574              :          end if
     575              :       case(bh_lg_t_sync_1)
     576            0 :          val = safe_log10(abs(b% t_sync_1) / secyer)
     577              :       case(bh_lg_t_sync_2)
     578            0 :          val = safe_log10(abs(b% t_sync_2) / secyer)
     579              :       case(bh_star_1_mass)
     580            0 :          val = b% m(1) / Msun
     581              :       case(bh_lg_star_1_mass)
     582            0 :          val = safe_log10(b% m(1) / Msun)
     583              :       case(bh_star_2_mass)
     584            0 :          val = b% m(2) / Msun
     585              :       case(bh_lg_star_2_mass)
     586            0 :          val = safe_log10(b% m(2) / Msun)
     587              :       case(bh_sum_of_masses)
     588            0 :          val = (b% m(1) + b% m(2)) / Msun
     589              :       case(bh_mass_ratio)
     590            0 :          val = b% m(2) / b% m(1)
     591              :       case(bh_obs_mass_ratio)
     592            0 :          val = min(b% m(2) / b% m(1), b% m(1) / b% m(2))
     593              :       case(bh_lg_mtransfer_rate)
     594            0 :          val = safe_log10(abs(b% step_mtransfer_rate) / Msun * secyer)
     595              :       case(bh_lg_mstar_dot_1)
     596            0 :          val = safe_log10(abs(b% component_mdot(1)) / Msun * secyer)
     597              :       case(bh_lg_mstar_dot_2)
     598            0 :          val = safe_log10(abs(b% component_mdot(2)) / Msun * secyer)
     599              :       case(bh_lg_system_mdot_1)
     600            0 :          val = safe_log10(abs(b% mdot_system_transfer(1)) / Msun * secyer)
     601              :       case(bh_lg_system_mdot_2)
     602            0 :          val = safe_log10(abs(b% mdot_system_transfer(2)) / Msun * secyer)
     603              :       case(bh_lg_wind_mdot_1)
     604            0 :          val = safe_log10(abs(b% mdot_system_wind(1)) / Msun * secyer)
     605              :       case(bh_lg_wind_mdot_2)
     606            0 :          val = safe_log10(abs(b% mdot_system_wind(2)) / Msun * secyer)
     607              :       case(bh_star_1_div_star_2_mass)
     608            0 :          val = b% m(1) / b% m(2)
     609              :       case(bh_delta_star_1_mass)
     610            0 :          val = b% m(1) - initial_mass(1)
     611              :       case(bh_delta_star_2_mass)
     612            0 :          val = b% m(2) - initial_mass(2)
     613              :       case(bh_lg_F_irr)
     614            0 :          val = safe_log10(b% s_donor% irradiation_flux)
     615              :       case(bh_fixed_xfer_fraction)
     616            0 :          val = b% fixed_xfer_fraction
     617              :       case(bh_eff_xfer_fraction)
     618            0 :          if (b% component_mdot(b% d_i) == 0d0) then
     619            0 :             val = 1d0
     620              :          else
     621            0 :             val = (-b% component_mdot(b% a_i)) / (b% component_mdot(b% d_i))
     622              :          end if
     623              :       case(bh_lg_mdot_edd)
     624            0 :          if (b% limit_retention_by_mdot_edd) then
     625            0 :             val = safe_log10(b% mdot_edd / Msun * secyer)
     626              :          else
     627            0 :             val = safe_log10(0d0)
     628              :          end if
     629              :       case(bh_mdot_edd_eta)
     630            0 :          if (b% limit_retention_by_mdot_edd) then
     631            0 :             val = b% mdot_edd_eta
     632              :          else
     633              :             val = 0d0
     634              :          end if
     635              :       case(bh_lg_accretion_luminosity)
     636            0 :          val = safe_log10(b% accretion_luminosity / Lsun)
     637              :       case(bh_bh_spin)
     638            0 :          if (b% point_mass_i /= 0) then
     639              :             val = sqrt(two_thirds) &
     640              :                * (b% eq_initial_bh_mass / min(b% m(b% point_mass_i), sqrt(6d0) * b% eq_initial_bh_mass)) &
     641              :                * (4d0 - sqrt(18d0 * pow2(b% eq_initial_bh_mass / &
     642            0 :                   min(b% m(b% point_mass_i), sqrt(6d0) * b% eq_initial_bh_mass)) - 2d0))
     643              :          else
     644              :             val = 0
     645              :          end if
     646              :       case(bh_v_orb_1)
     647            0 :          val = 2.0d0 * pi * b% m(2) / (b% m(1) + b% m(2)) * b% separation / b% period / 1.0d5
     648              :       case(bh_v_orb_2)
     649            0 :          val = 2.0d0 * pi * b% m(1) / (b% m(1) + b% m(2)) * b% separation / b% period / 1.0d5
     650              :       case(bh_J_orb)
     651            0 :          val = b% angular_momentum_j
     652              :       case(bh_J_spin_1)
     653            0 :          if (b% point_mass_i /= 1) then
     654            0 :             val = b% s1% total_angular_momentum
     655              :          else
     656              :             val = 0d0
     657              :          end if
     658              :       case(bh_J_spin_2)
     659            0 :          if (b% point_mass_i /= 2) then
     660            0 :             val = b% s2% total_angular_momentum
     661              :          else
     662            0 :             if (.not. b% model_twins_flag) then
     663              :                val = 0d0
     664              :             else
     665            0 :                val = b% s1% total_angular_momentum
     666              :             end if
     667              :          end if
     668              :       case(bh_J_total)
     669            0 :          val = b% angular_momentum_j
     670            0 :          if (b% point_mass_i /= 1) &
     671            0 :             val = val + b% s1% total_angular_momentum
     672            0 :          if (b% point_mass_i /= 2) then
     673            0 :             val = val + b% s2% total_angular_momentum
     674            0 :          else if (b% model_twins_flag) then
     675            0 :             val = val + b% s1% total_angular_momentum
     676              :          end if
     677            0 :          val = val
     678              :       case(bh_Jdot)
     679            0 :          val = b% jdot
     680              :       case(bh_jdot_mb)
     681            0 :          val = b% jdot_mb
     682              :       case(bh_jdot_gr)
     683            0 :          val = b% jdot_gr
     684              :       case(bh_jdot_ml)
     685            0 :          val = b% jdot_ml
     686              :       case(bh_jdot_ls)
     687            0 :          val = b% jdot_ls
     688              :       case(bh_jdot_missing_wind)
     689            0 :          val = b% jdot_missing_wind
     690              :       case(bh_extra_jdot)
     691            0 :          val = b% extra_jdot
     692              :       case(bh_accretion_mode)
     693            0 :          int_val = b% accretion_mode
     694            0 :          is_int_val = .true.
     695              :       case(bh_acc_am_div_kep_am)
     696            0 :          val = b% acc_am_div_kep_am
     697              :       case(bh_edot)
     698            0 :          val = b% edot
     699              :       case(bh_edot_tidal)
     700            0 :          val = b% edot_tidal
     701              :       case(bh_edot_enhance)
     702            0 :          val = b% edot_enhance
     703              :       case(bh_extra_edot)
     704            0 :          val = b% extra_edot
     705              :       case(bh_point_mass_index)
     706            0 :          is_int_val = .true.
     707            0 :          int_val = b% point_mass_i
     708              :       case(bh_ignore_rlof_flag)
     709            0 :          is_int_val = .true.
     710            0 :          if (b% ignore_rlof_flag) then
     711            0 :             int_val = 1d0
     712              :          else
     713              :             int_val = 0d0
     714              :          end if
     715              :       case(bh_model_twins_flag)
     716            0 :          is_int_val = .true.
     717            0 :          if (b% model_twins_flag) then
     718            0 :             int_val = 1d0
     719              :          else
     720              :             int_val = 0d0
     721              :          end if
     722              :       case(bh_CE_flag)
     723            0 :          is_int_val = .true.
     724            0 :          if (b% CE_flag) then
     725            0 :             int_val = 1d0
     726              :          else
     727              :             int_val = 0d0
     728              :          end if
     729              :       case(bh_CE_lambda1)
     730            0 :          val = b% CE_lambda1
     731              :       case(bh_CE_lambda2)
     732            0 :          val = b% CE_lambda2
     733              :       case(bh_CE_Ebind1)
     734            0 :          val = b% CE_Ebind1
     735              :       case(bh_CE_Ebind2)
     736            0 :          val = b% CE_Ebind2
     737              :       case(bh_CE_num1)
     738            0 :          is_int_val = .true.
     739            0 :          int_val = b% CE_num1
     740              :       case(bh_CE_num2)
     741            0 :          is_int_val = .true.
     742            0 :          int_val = b% CE_num2
     743              : 
     744              :       case default
     745            0 :          ierr = -1
     746              : 
     747              :       end select
     748              : 
     749            0 :    end subroutine binary_history_getval
     750              : 
     751            0 :    subroutine get_binary_history_specs(b, num, names, specs, report)
     752              : 
     753              :       use utils_lib
     754              :       use utils_def
     755              : 
     756              :       type (binary_info), pointer :: b
     757              :       integer, intent(in) :: num
     758              :       character (len = *), intent(in) :: names(:)
     759              :       integer, intent(out) :: specs(:)
     760              :       logical, intent(in) :: report
     761              : 
     762              :       integer :: i, ierr, n, j, iounit, t
     763              :       character (len = strlen) :: buffer, string
     764              : 
     765              :       include 'formats'
     766            0 :       ierr = 0
     767            0 :       if (num <= 0) return
     768            0 :       iounit = -1
     769            0 :       specs(1:num) = 0
     770            0 :       do i = 1, num
     771            0 :          buffer = names(i)
     772            0 :          n = len_trim(buffer) + 1
     773            0 :          buffer(n:n) = ' '
     774            0 :          j = 0
     775            0 :          t = token(iounit, n, j, buffer, string)
     776            0 :          if (t /= name_token) then
     777            0 :             if (len_trim(names(i)) > 0 .and. report) &
     778            0 :                write(*, *) 'bad value for name of history item ' // trim(names(i))
     779            0 :             specs(i) = -1
     780            0 :             ierr = 0
     781            0 :             cycle
     782              :          end if
     783              :          specs(i) = do1_binary_history_spec(&
     784            0 :             iounit, t, n, j, string, buffer, report, ierr)
     785            0 :          if (ierr /= 0) then
     786            0 :             if (report) write(*, *) 'get_binary_history_specs failed for ' // trim(names(i))
     787            0 :             specs(i) = -1
     788            0 :             ierr = 0
     789              :          end if
     790              :       end do
     791              : 
     792              :    end subroutine get_binary_history_specs
     793              : 
     794              : 
     795            0 :    subroutine get_binary_history_values(b, num, specs, &
     796            0 :       is_int_value, int_values, values, failed_to_find_value)
     797              :       ! note: this doesn't handle user-defined extra columns
     798              : 
     799              :       use utils_lib
     800              :       use utils_def
     801              : 
     802              :       type (binary_info), pointer :: b
     803              :       integer, intent(in) :: num
     804              :       integer, intent(in) :: specs(:)
     805              :       logical, intent(out) :: is_int_value(:)
     806              :       integer, intent(out) :: int_values(:)
     807              :       real(dp), intent(inout) :: values(:)
     808              :       logical, intent(out) :: failed_to_find_value(:)
     809              : 
     810              :       integer :: i, c, ierr
     811              : 
     812              :       include 'formats'
     813            0 :       ierr = 0
     814              : 
     815            0 :       do i = 1, num
     816            0 :          failed_to_find_value(i) = .false.
     817            0 :          c = specs(i)
     818            0 :          if (c <= 0) then
     819            0 :             failed_to_find_value(i) = .true.
     820              :          else
     821              :             call binary_history_getval(&
     822            0 :                b, c, values(i), int_values(i), is_int_value(i), ierr)
     823            0 :             if (ierr /= 0) then
     824            0 :                failed_to_find_value(i) = .true.
     825            0 :                ierr = 0
     826              :             end if
     827              :          end if
     828              :       end do
     829              : 
     830            0 :    end subroutine get_binary_history_values
     831              : 
     832            0 :    logical function get1_binary_hist_value(b, name, val)
     833              :       ! includes other_history_columns from run_binary_extras
     834              :       use utils_lib, only : integer_dict_lookup
     835              :       type (binary_info), pointer :: b
     836              :       character (len = *) :: name
     837              :       real(dp), intent(out) :: val
     838              :       integer :: i, ierr, num_extra_cols
     839            0 :       character (len = 80), pointer, dimension(:) :: extra_col_names
     840            0 :       real(dp), pointer, dimension(:) :: extra_col_vals
     841              :       include 'formats'
     842              : 
     843            0 :       get1_binary_hist_value = .false.
     844            0 :       call integer_dict_lookup(b% binary_history_names_dict, name, i, ierr)
     845            0 :       if (ierr /= 0 .or. i <= 0) return  ! didn't find it
     846            0 :       if (associated(b% pg% pgbinary_hist)) then
     847            0 :          if (associated(b% pg% pgbinary_hist% vals)) then
     848            0 :             if (size(b% pg% pgbinary_hist% vals, dim = 1) >= i) then
     849            0 :                val = b% pg% pgbinary_hist% vals(i)
     850            0 :                get1_binary_hist_value = .true.
     851            0 :                return
     852              :             end if
     853              :          end if
     854              :       end if
     855              : 
     856              :       ! try extras
     857            0 :       if (associated(b% how_many_extra_binary_history_columns) .and. &
     858              :          associated(b% data_for_extra_binary_history_columns)) then
     859            0 :          num_extra_cols = b% how_many_extra_binary_history_columns(b% binary_id)
     860            0 :          if (num_extra_cols > 0) then
     861              :             allocate(&
     862              :                extra_col_names(num_extra_cols), &
     863            0 :                extra_col_vals(num_extra_cols), stat = ierr)
     864              :             call b% data_for_extra_binary_history_columns(&
     865            0 :                b% binary_id, num_extra_cols, extra_col_names, extra_col_vals, ierr)
     866            0 :             do i = 1, num_extra_cols
     867            0 :                if (extra_col_names(i) == name) then
     868            0 :                   val = extra_col_vals(i)
     869            0 :                   get1_binary_hist_value = .true.
     870            0 :                   exit
     871              :                end if
     872              :             end do
     873            0 :             deallocate(extra_col_names, extra_col_vals)
     874            0 :             if (get1_binary_hist_value) return
     875              :          end if
     876              :       end if
     877              : 
     878            0 :    end function get1_binary_hist_value
     879              : 
     880              : end module binary_history
        

Generated by: LCOV version 2.0-1