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

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2019  Pablo Marchant & 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 binary_do_one_utils
      21              : 
      22              :       use binary_def
      23              :       use const_def, only: dp, pi, msun, rsun, secyer, standard_cgrav
      24              :       use math_lib
      25              : 
      26              :       implicit none
      27              : 
      28              :       contains
      29              : 
      30            0 :       subroutine write_binary_terminal_header(b)
      31              :          type (binary_info), pointer :: b
      32            0 :          if (b% model_number <= b% recent_binary_log_header) return
      33            0 :          if (b% just_wrote_binary_terminal_header) return
      34            0 :          b% recent_binary_log_header = b% model_number
      35            0 :          call do_show_binary_terminal_header(b)
      36            0 :          b% just_wrote_binary_terminal_header = .true.
      37              :       end subroutine write_binary_terminal_header
      38              : 
      39              : 
      40            0 :       subroutine do_show_binary_log_description(id, ierr)
      41              :          integer, intent(in) :: id
      42              :          integer, intent(out) :: ierr
      43              :          type (binary_info), pointer :: b
      44              :          ierr = 0
      45            0 :          call get_binary_ptr(id, b, ierr)
      46            0 :          if (ierr /= 0) return
      47            0 :          write(*,'(A)')
      48            0 :          write(*,'(a)') " The binary terminal output contains the following information"
      49            0 :          write(*,'(A)')
      50            0 :          write(*,'(a)') "      'step' is the number of steps since the start of the run,"
      51            0 :          write(*,'(a)') "      'lg_dt' is log10 timestep in years,"
      52            0 :          write(*,'(a)') "      'age_yr' is the simulated years since the start run,"
      53            0 :          write(*,'(a)') "      'M1+M2' is the total mass of the system (Msun),"
      54            0 :          write(*,'(a)') "      'M1' is the mass of the primary (Msun)"
      55            0 :          write(*,'(a)') "      'M2' is the mass of the secondary (Msun)"
      56            0 :          write(*,'(a)') "      'separ' is the semi-major axis of the orbit (Rsun),"
      57            0 :          write(*,'(a)') "      'R1' is the radius of the primary (Rsun)"
      58            0 :          write(*,'(a)') "      'R2' is the radius of the secondary (Rsun)"
      59            0 :          write(*,'(a)') "      'Porb' is the orbital period (days),"
      60            0 :          write(*,'(a)') "      'P1' is the rotation period of star 1 (days, zero if not modeling rotation),"
      61            0 :          write(*,'(a)') "      'P2' is the rotation period of star 2 (days, zero if not modeling rotation),"
      62            0 :          write(*,'(a)') "      'e' orbital eccentricity,"
      63            0 :          write(*,'(a)') "      'dot_e' time derivative of e (1/yr),"
      64            0 :          write(*,'(a)') "      'Eorb' orbital energy G*M1*M2/2*separation (ergs),"
      65            0 :          write(*,'(a)') "      'M2/M1' mass ratio,"
      66            0 :          write(*,'(a)') "      'vorb1' orbital velocity of star 1 (km/s),"
      67            0 :          write(*,'(a)') "      'vorb2' orbital velocity of star 2 (km/s),"
      68            0 :          write(*,'(a)') "      'pm_i' index of star evolved as point mass, zero if both stars are modeled,"
      69            0 :          write(*,'(a)') "      'RL1' Roche lobe radius of star 1 (Rsun),"
      70            0 :          write(*,'(a)') "      'Rl2' Roche lobe radius of star 2 (Rsun),"
      71            0 :          write(*,'(a)') "      'donor_i' index of star taken as donor,"
      72            0 :          write(*,'(a)') "      'RL_gap1' (R1-Rl1)/Rl1,"
      73            0 :          write(*,'(a)') "      'RL_gap2' (R2-Rl2)/Rl2,"
      74            0 :          write(*,'(a)') "      'dot_Mmt', mass transfer rate (Msun/yr),"
      75            0 :          write(*,'(a)') "      'dot_M1', time derivative for the mass of star 1 (Msun/yr),"
      76            0 :          write(*,'(a)') "      'dot_M2', time derivative for the mass of star 2 (Msun/yr),"
      77            0 :          write(*,'(a)') "      'eff', mass transfer efficiency, computed as -dot_M2/dot_M1 (zero if dot_M1=0),"
      78            0 :          write(*,'(a)') "      'dot_Medd', Eddington accretion rate (Msun/yr),"
      79            0 :          write(*,'(a)') "      'L_acc', accretion luminosity when accreting to a point mass (ergs/s),"
      80            0 :          write(*,'(a)') "      'Jorb', orbital angular momentum (g*cm^2/s)"
      81            0 :          write(*,'(a)') "      'spin1', spin angular momentum of star 1 (g*cm^2/s),"
      82            0 :          write(*,'(a)') "      'spin2', spin angular momentum of star 2 (g*cm^2/s),"
      83            0 :          write(*,'(a)') "      'dot_J', time derivative of Jorb (g*cm^2/s^2),"
      84            0 :          write(*,'(a)') "      'dot_Jgr', time derivative of Jorb due to gravitational waves (g*cm^2/s^2),"
      85            0 :          write(*,'(a)') "      'dot_Jml', time derivative of Jorb due to mass loss (g*cm^2/s^2),"
      86            0 :          write(*,'(a)') "      'dot_Jmb', time derivative of Jorb due to magnetic braking (g*cm^2/s^2),"
      87            0 :          write(*,'(a)') "      'dot_Jls', time derivative of Jorb due to spin-orbit coupling (g*cm^2/s^2),"
      88            0 :          write(*,'(a)') "      'rlo_iters', number of iterations for implicit calculation of mass transfer,"
      89            0 :          write(*,'(A)')
      90            0 :          write(*,'(a)') " All this and more can be saved in binary_history.data during the run."
      91              :       end subroutine do_show_binary_log_description
      92              : 
      93              : 
      94            0 :       subroutine do_show_binary_terminal_header(b)
      95              :          type (binary_info), pointer :: b
      96            0 :          call output_binary_terminal_header(b,terminal_iounit)
      97            0 :          if (b% extra_binary_terminal_iounit > 0) &
      98            0 :             call output_binary_terminal_header(b,b% extra_binary_terminal_iounit)
      99            0 :       end subroutine do_show_binary_terminal_header
     100              : 
     101              : 
     102            0 :       subroutine output_binary_terminal_header(b,io)
     103              :          type (binary_info), pointer :: b
     104              :          integer, intent(in) :: io
     105              :          write(io,'(a)') &
     106              :             '_______________________________________________________________________' // &
     107            0 :             '___________________________________________________________________________'
     108            0 :          write(io,'(A)')
     109              :          write(io,'(a)') &
     110              :             'binary_step      M1+M2      separ       Porb          e      M2/M1' // &
     111            0 :             '       pm_i    donor_i    dot_Mmt        eff       Jorb      dot_J    dot_Jmb'
     112              :          write(io,'(a)') &
     113              :             '      lg_dt         M1         R1         P1      dot_e      vorb1' // &
     114            0 :             '        RL1    Rl_gap1     dot_M1   dot_Medd      spin1    dot_Jgr    dot_Jls'
     115              :          write(io,'(a)') &
     116              :             '     age_yr         M2         R2         P2       Eorb      vorb2' // &
     117            0 :             '        RL2    Rl_gap2     dot_M2      L_acc      spin2    dot_Jml  rlo_iters'
     118              :          write(io,'(a)') &
     119              :             '_______________________________________________________________________' // &
     120            0 :             '___________________________________________________________________________'
     121            0 :          write(io,'(A)')
     122              : 
     123            0 :       end subroutine output_binary_terminal_header
     124              : 
     125              : 
     126            0 :       subroutine do_binary_terminal_summary(b)
     127              :          type (binary_info), pointer :: b
     128            0 :          call output_binary_terminal_summary(b,terminal_iounit)
     129            0 :          if (b% extra_binary_terminal_iounit > 0) then
     130            0 :             call output_binary_terminal_summary(b,b% extra_binary_terminal_iounit)
     131            0 :             flush(b% extra_binary_terminal_iounit)
     132              :          end if
     133            0 :       end subroutine do_binary_terminal_summary
     134              : 
     135              : 
     136            0 :       subroutine output_binary_terminal_summary(b,io)
     137              :          type (binary_info), pointer :: b
     138              :          integer, intent(in) :: io
     139              : 
     140              :          real(dp) :: age, time_step, total_mass
     141            0 :          real(dp) :: Eorb, vorb1, vorb2, dot_M1, dot_M2, eff, dot_Medd, spin1, spin2, P1, P2
     142              :          integer :: model, ierr, rlo_iters
     143              :          character (len=90) :: fmt, fmt1, fmt2, fmt3, fmt4, fmt5, fmt6
     144              : 
     145              :          include 'formats'
     146              : 
     147            0 :          age = b% binary_age
     148            0 :          time_step = b% time_step
     149            0 :          model = b% model_number
     150            0 :          rlo_iters = b% num_tries
     151              : 
     152            0 :          total_mass = (b% m(1) + b% m(2))/Msun
     153              : 
     154            0 :          vorb1 = 2.0d0 * pi * b% m(2)/(b% m(1) + b% m(2)) * b% separation / b% period / 1.0d5
     155            0 :          vorb2 = 2.0d0 * pi * b% m(1)/(b% m(1) + b% m(2)) * b% separation / b% period / 1.0d5
     156            0 :          Eorb = -standard_cgrav * b% m(1) * b% m(2) / (2*b% separation)
     157            0 :          dot_M1 = b% component_mdot(1)/Msun*secyer
     158            0 :          if (abs(dot_M1) < 1d-99) dot_M1 = 0d0
     159            0 :          dot_M2 = b% component_mdot(2)/Msun*secyer
     160            0 :          if (abs(dot_M2) < 1d-99) dot_M2 = 0d0
     161            0 :          if (b% component_mdot(b% d_i) == 0d0) then
     162            0 :             eff = 1d0
     163              :          else
     164            0 :             eff = -b% component_mdot(b% a_i)/b% component_mdot(b% d_i)
     165              :          end if
     166            0 :          if (b% limit_retention_by_mdot_edd) then
     167            0 :             dot_Medd = b% mdot_edd/Msun*secyer
     168              :          else
     169            0 :             dot_Medd = 1d99
     170              :          end if
     171            0 :          if (b% point_mass_i /= 1) then
     172            0 :             spin1 = b% s1% total_angular_momentum
     173              :          else
     174            0 :             spin1 = 0d0
     175              :          end if
     176              : 
     177            0 :          if (b% point_mass_i /= 2) then
     178            0 :             spin2 = b% s2% total_angular_momentum
     179              :          else
     180            0 :             if (.not. b% model_twins_flag) then
     181            0 :                spin2 = 0d0
     182              :             else
     183            0 :                spin2 = b% s1% total_angular_momentum
     184              :             end if
     185              :          end if
     186              : 
     187            0 :          P1 = 0d0
     188            0 :          if (b% point_mass_i /= 1) then
     189            0 :             if (b% s1% rotation_flag) then
     190            0 :                if (abs(b% s1% omega_avg_surf) > 0) then
     191            0 :                   P1 = 2*pi/(b% s1% omega_avg_surf*24d0*3600d0)
     192              :                end if
     193              :             end if
     194              :          end if
     195              : 
     196            0 :          P2 = 0d0
     197            0 :          if (b% point_mass_i /= 2)then
     198            0 :             if (b% s2% rotation_flag) then
     199            0 :                if (abs(b% s2% omega_avg_surf) > 0) then
     200            0 :                   P2 = 2*pi/(b% s2% omega_avg_surf*24d0*3600d0)
     201              :                end if
     202              :             end if
     203            0 :          else if (b% model_twins_flag) then
     204            0 :             if (b% s1% rotation_flag) then
     205            0 :                if (abs(b% s1% omega_avg_surf) > 0) then
     206            0 :                   P2 = 2*pi/(b% s1% omega_avg_surf*24d0*3600d0)
     207              :                end if
     208              :             end if
     209              :          end if
     210              : 
     211            0 :          ierr = 0
     212              : 
     213              :          !make format strings for first line of output
     214              :          !step and m1+m2
     215            0 :          if (total_mass >= 1d2) then
     216            0 :             fmt1 = '(a3,i8,1pe11.3,0p,'
     217              :          else
     218            0 :             fmt1 = '(a3,i8,f11.6,'
     219              :          end if
     220              :          !separation
     221            0 :          if (b% separation/Rsun >= 1d2) then
     222            0 :             fmt2 = '1pe11.3,0p,'
     223              :          else
     224            0 :             fmt2 = 'f11.6,'
     225              :          end if
     226              :          !Porb
     227            0 :          if (b% period/(3600d0*24d0) >= 1d2) then
     228            0 :             fmt3 = '1pe11.3,0p,'
     229              :          else
     230            0 :             fmt3 = 'f11.6,'
     231              :          end if
     232              :          !eccentricity
     233            0 :          if (b% eccentricity >= 1d-2) then
     234            0 :             fmt4 = 'f11.6,'
     235              :          else
     236            0 :             fmt4 = '1pe11.3,0p,'
     237              :          end if
     238              :          !mass ratio, pm_i, donor_index and dot_Mmt
     239            0 :          if (b% m(2)/b% m(1) >= 1d-2) then
     240            0 :             fmt5 = 'f11.6,2i11,1pe11.3,0p,'
     241              :          else
     242            0 :             fmt5 = '1pe11.3,0p,2i11,1pe11.3,0p,'
     243              :          end if
     244              :          !eff
     245            0 :          if (eff >= 1d-2) then
     246            0 :             fmt6 = 'f11.6,3(1pe11.3))'
     247              :          else
     248            0 :             fmt6 = '4(1pe11.3))'
     249              :          end if
     250              : 
     251              : 
     252            0 :          fmt = trim(fmt1) // trim(fmt2) // trim(fmt3) // trim(fmt4) // trim(fmt5) // trim(fmt6)
     253              :          write(io,fmt=fmt) &
     254            0 :             'bin', &
     255            0 :             model, &
     256            0 :             total_mass, &
     257            0 :             b% separation / Rsun, &
     258            0 :             b% period / (3600d0*24d0), &
     259            0 :             b% eccentricity, &
     260            0 :             b% m(2)/b% m(1), &
     261            0 :             b% point_mass_i, &
     262            0 :             b% d_i, &
     263            0 :             b% step_mtransfer_rate/Msun*secyer, &
     264            0 :             eff, &
     265            0 :             b% angular_momentum_j, &
     266            0 :             b% jdot, &
     267            0 :             b% jdot_mb
     268              : 
     269              :          !make format strings for second line of output
     270              :          !lg_dt and M1
     271            0 :          if (b% m(1)/Msun >= 1d2) then
     272            0 :             fmt1 = '(f11.6,1pe11.3,0p,'
     273              :          else
     274            0 :             fmt1 = '(2f11.6,'
     275              :          end if
     276              :          !R1
     277            0 :          if (b% r(1)/Rsun >= 1d2) then
     278            0 :             fmt2 = '1pe11.3,0p,'
     279              :          else
     280            0 :             fmt2 = 'f11.6,'
     281              :          end if
     282              :          !P1, dot_e
     283            0 :          if (P1 >= 1d2) then
     284            0 :             fmt3 = '2(1pe11.3),0p'
     285              :          else
     286            0 :             fmt3 = 'f11.6,1pe11.3,0p'
     287              :          end if
     288              :          !vorb1
     289            0 :          if (vorb1 >= 1d-2 .and. vorb1 < 1d4) then
     290            0 :             fmt4 = 'f11.6,'
     291              :          else
     292            0 :             fmt4 = '1pe11.3,0p,'
     293              :          end if
     294              :          !RL1 and the rest
     295            0 :          if (b% rl(1)/Rsun >= 1d2) then
     296            0 :             fmt5 = '7(1pe11.3))'
     297              :          else
     298            0 :             fmt5 = 'f11.6,6(1pe11.3))'
     299              :          end if
     300              : 
     301            0 :          fmt = trim(fmt1) // trim(fmt2) // trim(fmt3) // trim(fmt4) // trim(fmt5)
     302              :          write(io,fmt=fmt) &
     303            0 :             safe_log10(time_step),  &
     304            0 :             b% m(1)/Msun, &
     305            0 :             b% r(1)/Rsun, &
     306            0 :             P1, &
     307            0 :             b% edot, &
     308            0 :             vorb1, &
     309            0 :             b% rl(1)/Rsun, &
     310            0 :             b% rl_relative_gap(1), &
     311            0 :             dot_M1, &
     312            0 :             dot_Medd, &
     313            0 :             spin1, &
     314            0 :             b% jdot_gr, &
     315            0 :             b% jdot_ls
     316              : 
     317              :          !make format strings for third line of output
     318              :          !age_yr and M2
     319            0 :          if (b% m(2)/Msun >= 1d2) then
     320            0 :             fmt1 = '(1pe11.4,0p,1pe11.3,0p,'
     321              :          else
     322            0 :             fmt1 = '(1pe11.4,0p,f11.6,'
     323              :          end if
     324              :          !R2
     325            0 :          if (b% r(2)/Rsun >= 1d2) then
     326            0 :             fmt2 = '1pe11.3,0p,'
     327              :          else
     328            0 :             fmt2 = 'f11.6,'
     329              :          end if
     330              :          !P2, Eorb
     331            0 :          if (P2 >= 1d2) then
     332            0 :             fmt3 = '2(1pe11.3),0p'
     333              :          else
     334            0 :             fmt3 = 'f11.6,1pe11.3,0p'
     335              :          end if
     336              :          !vorb2
     337            0 :          if (vorb2 >= 1d-2 .and. vorb2 < 1d4) then
     338            0 :             fmt4 = 'f11.6,'
     339              :          else
     340            0 :             fmt4 = '1pe11.3,0p,'
     341              :          end if
     342              :          !RL2 and the rest
     343            0 :          if (b% rl(2)/Rsun >= 1d2) then
     344            0 :             fmt5 = '6(1pe11.3),i11)'
     345              :          else
     346            0 :             fmt5 = 'f11.6,5(1pe11.3),0p,i11)'
     347              :          end if
     348              : 
     349            0 :          fmt = trim(fmt1) // trim(fmt2) // trim(fmt3) // trim(fmt4) // trim(fmt5)
     350              :          write(io,fmt=fmt) &
     351            0 :             age,  &
     352            0 :             b% m(2)/Msun, &
     353            0 :             b% r(2)/Rsun, &
     354            0 :             P2, &
     355            0 :             Eorb, &
     356            0 :             vorb2, &
     357            0 :             b% rl(2)/Rsun, &
     358            0 :             b% rl_relative_gap(2), &
     359            0 :             dot_M2, &
     360            0 :             b% accretion_luminosity, &
     361            0 :             spin2, &
     362            0 :             b% jdot_ml, &
     363            0 :             rlo_iters
     364              : 
     365            0 :          write(io,'(A)')
     366              : 
     367            0 :          b% just_wrote_binary_terminal_header = .false.
     368              : 
     369            0 :       end subroutine output_binary_terminal_summary
     370              : 
     371              : 
     372              :       end module binary_do_one_utils
     373              : 
        

Generated by: LCOV version 2.0-1