LCOV - code coverage report
Current view: top level - star/private - pulse_cafein.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 277 0
Test Date: 2025-05-08 18:23:42 Functions: 0.0 % 6 0

            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 pulse_cafein
      21              : 
      22              :   use star_private_def
      23              :   use const_def, only: dp, pi, pi4, crad, clight, msun, rsun, cgas
      24              :   use utils_lib
      25              :   use atm_def
      26              :   use atm_support
      27              :   use pulse_utils
      28              : 
      29              :   implicit none
      30              : 
      31              :   private
      32              :   public :: get_cafein_data
      33              :   public :: write_cafein_data
      34              : 
      35              :   integer, parameter :: NCOL = 35
      36              : 
      37              : contains
      38              : 
      39            0 :   subroutine get_cafein_data (id, &
      40              :        add_center_point, keep_surface_point, add_atmosphere, global_data, point_data, ierr)
      41              : 
      42              :     integer, intent(in)                :: id
      43              :     logical, intent(in)                :: add_center_point
      44              :     logical, intent(in)                :: keep_surface_point
      45              :     logical, intent(in)                :: add_atmosphere
      46              :     real(dp), allocatable, intent(out) :: global_data(:)
      47              :     real(dp), allocatable, intent(out) :: point_data(:,:)
      48              :     integer, intent(out)               :: ierr
      49              : 
      50              :     type(star_info), pointer :: s
      51              :     integer                  :: n_atm
      52              :     integer                  :: nn_atm
      53              :     integer                  :: n_env
      54              :     integer                  :: nn_env
      55              :     integer                  :: nn
      56            0 :     real(dp)                 :: R_star
      57            0 :     real(dp)                 :: M_star
      58            0 :     real(dp)                 :: P_c
      59            0 :     real(dp)                 :: T_c
      60            0 :     real(dp)                 :: rho_c
      61            0 :     real(dp)                 :: s_units
      62            0 :     real(dp)                 :: g_units
      63            0 :     real(dp)                 :: cm_units
      64            0 :     real(dp)                 :: erg_units
      65            0 :     real(dp)                 :: K_units
      66            0 :     real(dp), allocatable    :: l_rad(:)
      67              :     integer                  :: j
      68              :     integer                  :: k
      69              : 
      70              :     ! Get model data for CAFein output
      71              : 
      72            0 :     call get_star_ptr(id, s, ierr)
      73            0 :     if (ierr /= 0) then
      74            0 :        write(*,*) 'bad star id for get_cafein_data'
      75            0 :        return
      76              :     end if
      77              : 
      78              :     ! Determine data dimensions
      79              : 
      80            0 :     if (add_atmosphere) then
      81            0 :        call build_atm(s, s%L(1), s%r(1), s%Teff, s%m_grav(1), s%cgrav(1), ierr)
      82            0 :        if (ierr /= 0) then
      83            0 :           write(*,*) 'failed in build_atm'
      84            0 :           return
      85              :        end if
      86            0 :        n_atm = s%atm_structure_num_pts
      87            0 :        nn_atm = n_atm - 1
      88              :     else
      89              :        n_atm = 0
      90              :        nn_atm = 0
      91              :     end if
      92              : 
      93            0 :     n_env = s%nz
      94              : 
      95            0 :     if (keep_surface_point) then
      96              :        nn_env = n_env
      97              :     else
      98            0 :        nn_env = n_env - 1
      99              :     end if
     100              : 
     101            0 :     if (add_center_point) then
     102            0 :        nn = nn_env + nn_atm + 1
     103              :     else
     104            0 :        nn = nn_env + nn_atm
     105              :     end if
     106              : 
     107              :     ! Store global data
     108              : 
     109            0 :     allocate(global_data(13))
     110              : 
     111            0 :     M_star = s%m_grav(1)
     112            0 :     R_star = Rsun*s%photosphere_r
     113              : 
     114            0 :     P_c = eval_center(s%rmid, s%Peos, 1, s%nz)
     115            0 :     T_c = eval_center(s%rmid, s%T, 1, s%nz)
     116            0 :     rho_c = eval_center(s%rmid, s%rho, 1, s%nz)
     117              : 
     118            0 :     s_units = SQRT(pow3(R_star)/(s%cgrav(1)*M_star))
     119            0 :     g_units = M_star
     120            0 :     cm_units = R_star
     121            0 :     erg_units = s%cgrav(1)*M_star**2/R_star
     122            0 :     K_units = s%cgrav(1)*M_star**2/(R_star*cgas)
     123              : 
     124            0 :     global_data(1) = M_star/Msun
     125            0 :     global_data(2) = R_star/Rsun
     126            0 :     global_data(3) = s%L(1)
     127            0 :     global_data(4) = P_c
     128            0 :     global_data(5) = T_c
     129            0 :     global_data(6) = rho_c
     130            0 :     global_data(7) = s%Teff
     131            0 :     global_data(8) = s_units
     132            0 :     global_data(9) = g_units
     133            0 :     global_data(10) = cm_units
     134            0 :     global_data(11) = erg_units
     135            0 :     global_data(12) = K_units
     136            0 :     global_data(13) = 0.d0
     137              : 
     138              :     ! Store point data. IMPORTANT NOTE: CAFein is ambiguous about
     139              :     ! which luminosity (total l or radiative l_rad) should be stored
     140              :     ! in output files (both as the Lr field, and for calculation of
     141              :     ! the dlnLr/dlnr, c_3 and c_4 fields). From context (i.e., reading
     142              :     ! the CAFein code), both dlnL/dlnr and the c_3/c_4 coefficients
     143              :     ! should be calculated using l_rad; however, it seems more useful
     144              :     ! for the Lr field to contain l. This is what the following code
     145              :     ! does.
     146              : 
     147            0 :     allocate(point_data(NCOL,nn))
     148              : 
     149            0 :     allocate(l_rad(nn))
     150              : 
     151            0 :     j = 1
     152              : 
     153              :     ! Atmosphere (we skip the point at the base of the atm to smooth
     154              :     ! the transition)
     155              : 
     156            0 :     atm_loop : do k = 1, n_atm-1
     157            0 :        call store_point_data_atm(j, k)
     158            0 :        j = j + 1
     159              :     end do atm_loop
     160              : 
     161              :     ! Envelope
     162              : 
     163            0 :     env_loop : do k = 1, n_env
     164              : 
     165            0 :        if (k == 1 .AND. .NOT. keep_surface_point) cycle env_loop
     166              : 
     167            0 :        call store_point_data_env(j, k)
     168            0 :        j = j + 1
     169              : 
     170              :     end do env_loop
     171              : 
     172              :     ! Center
     173              : 
     174            0 :     if (add_center_point) then
     175            0 :        call store_point_data_ctr(j)
     176            0 :        j = j + 1
     177              :     end if
     178              : 
     179              :     ! Check that all point data has correctly been calculated
     180              : 
     181            0 :     if (j /= nn+1) call mesa_error(__FILE__,__LINE__,'Invalid cell index in get_cafein_data')
     182              : 
     183              :     ! Reverse the data ordering (CAFein format is center-to-surface)
     184              : 
     185            0 :     point_data = point_data(:,nn:1:-1)
     186              : 
     187            0 :     l_rad = l_rad(nn:1:-1)
     188              : 
     189              :    ! Set remaining point data
     190              : 
     191              :     associate ( &
     192              :          r => point_data(5,:), &
     193              :          U => point_data(8,:), &
     194              :          N2 => point_data(10,:), &
     195              :          V => point_data(14,:), &
     196              :          nabla_ad => point_data(15,:), &
     197              :          c_2_fit => point_data(22,:), &
     198              :          dlnLr_dlnr => point_data(25,:), &
     199              :          surf_r_rad_beg => point_data(27,:), &
     200              :          surf_r_rad_end => point_data(28,:), &
     201              :          U_U_surf => point_data(34,:), &
     202              :          c_2 => point_data(35,:))
     203              : 
     204            0 :       c_2 = c_2 + nabla_ad*(log_deriv(r, nabla_ad, dy_a=0d0) + V)
     205            0 :       c_2_fit = c_2
     206              : 
     207            0 :       dlnLr_dlnr = log_deriv(r, l_rad, dy_a=3d0)
     208              : 
     209            0 :       U_U_surf = U/U(nn)
     210              : 
     211            0 :       surf_r_rad_beg = R_star
     212              : 
     213            0 :       do j = 1, nn
     214            0 :          surf_r_rad_end = r(j)
     215            0 :          if (N2(j) < 0d0) exit
     216              :       end do
     217              : 
     218              :     end associate
     219              : 
     220              :     ! Convert dimensioned data to dimensionless
     221              : 
     222              :     associate ( &
     223              :          m => point_data(1,:), &
     224              :          logrho => point_data(2,:) , &
     225              :          logP => point_data(3,:), &
     226              :          logT => point_data(4,:), &
     227              :          r => point_data(5,:), &
     228              :          N2 => point_data(10,:), &
     229              :          L2_ll1 => point_data(11,:), &
     230              :          g => point_data(12,:), &
     231              :          l => point_data(13,:), &
     232              :          C_P => point_data(17,:), &
     233              :          P_scale => point_data(26,:), &
     234              :          surf_r_rad_beg => point_data(27,:), &
     235              :          surf_r_rad_end => point_data(28,:), &
     236              :          entropy => point_data(30,:), &
     237              :          kap => point_data(31,:))
     238              : 
     239            0 :       m = m/g_units
     240              : 
     241            0 :       r = r/cm_units
     242            0 :       l = l/(erg_units/s_units)
     243              : 
     244            0 :       logrho = logrho - log10(g_units/cm_units**3)
     245            0 :       logP = logP - log10(erg_units/cm_units**3)
     246            0 :       logT = logT - log10(K_units)
     247              : 
     248            0 :       N2 = N2*s_units**2
     249            0 :       L2_ll1 = L2_ll1*s_units**2
     250              : 
     251            0 :       g = g/(cm_units/s_units**2)
     252              : 
     253            0 :       C_p = C_p/(erg_units/(K_units*g_units))
     254              : 
     255            0 :       P_scale = P_scale/cm_units
     256              : 
     257            0 :       surf_r_rad_beg = surf_r_rad_beg/cm_units
     258            0 :       surf_r_rad_end = surf_r_rad_end/cm_units
     259              : 
     260            0 :       entropy = entropy/(erg_units/(K_units*g_units))
     261              : 
     262            0 :       kap = kap/(cm_units**2/g_units)
     263              : 
     264              :     end associate
     265              : 
     266              :     ! Tidy up
     267              : 
     268            0 :     if (ASSOCIATED(s%atm_structure)) then
     269            0 :        deallocate(s%atm_structure)
     270              :     end if
     271              : 
     272            0 :     return
     273              : 
     274              :   contains
     275              : 
     276            0 :     subroutine store_point_data_atm (j, k)
     277              : 
     278              :       integer, intent(in) :: j
     279              :       integer, intent(in) :: k
     280              : 
     281            0 :       real(dp) :: rho
     282            0 :       real(dp) :: P
     283            0 :       real(dp) :: T
     284            0 :       real(dp) :: kap_rho
     285            0 :       real(dp) :: kap_T
     286            0 :       real(dp) :: kap_ad
     287            0 :       real(dp) :: eps
     288              : 
     289              :       ! Store data associated with atmosphere point k into the
     290              :       ! point_data array at position j
     291              : 
     292              :       associate ( &
     293              :            m => point_data(1,j), &
     294              :            logrho => point_data(2,j) , &
     295              :            logP => point_data(3,j), &
     296              :            logT => point_data(4,j), &
     297              :            r => point_data(5,j), &
     298              :            V_g => point_data(6,j), &
     299              :            As => point_data(7,j), &
     300              :            U => point_data(8,j), &
     301              :            c_1 => point_data(9,j), &
     302              :            N2 => point_data(10,j), &
     303              :            L2_ll1 => point_data(11,j), &
     304              :            g => point_data(12,j), &
     305              :            l => point_data(13,j), &
     306              :            V => point_data(14,j), &
     307              :            nabla_ad => point_data(15,j), &
     308              :            nabla => point_data(16,j), &
     309              :            C_P => point_data(17,j), &
     310              :            delta => point_data(18,j), &
     311              :            kap_S => point_data(19,j), &
     312              :            eps_ad => point_data(20,j), &
     313              :            eps_S => point_data(21,j), &
     314              :            c_3 => point_data(23,j), &
     315              :            c_4 => point_data(24,j), &
     316              :            P_scale => point_data(26,j), &
     317              :            Gamma_1 => point_data(29,j), &
     318              :            entropy => point_data(30,j), &
     319              :            kap => point_data(31,j), &
     320              :            chi_rho => point_data(32,j), &
     321              :            chi_T => point_data(33,j), &
     322              :            c_2 => point_data(35,j))
     323              : 
     324            0 :         m = s%m_grav(1)  !+ s%atm_structure(atm_delta_m,k)
     325            0 :         r = s%r(1) + s%atm_structure(atm_delta_r,k)
     326            0 :         l = s%L(1)
     327              : 
     328            0 :         logrho = s%atm_structure(atm_lnd,k)/log(10d0)
     329            0 :         logP = s%atm_structure(atm_lnP,k)/log(10d0)
     330            0 :         logT = s%atm_structure(atm_lnT,k)/log(10d0)
     331              : 
     332            0 :         rho = pow(10d0, logrho)
     333            0 :         P = pow(10d0, logP)
     334            0 :         T = pow(10d0, logT)
     335              : 
     336            0 :         nabla_ad = s%atm_structure(atm_grada,k)
     337            0 :         nabla = s%atm_structure(atm_gradT,k)
     338            0 :         C_P = s%atm_structure(atm_cp,k)
     339            0 :         delta = s%atm_structure(atm_chiT,k)/s%atm_structure(atm_chiRho,k)
     340            0 :         Gamma_1 = s%atm_structure(atm_gamma1,k)
     341            0 :         entropy = 0d0  ! No entropy data in surface layers
     342            0 :         chi_rho = s%atm_structure(atm_chiRho,k)
     343            0 :         chi_T = s%atm_structure(atm_chiT,k)
     344              : 
     345            0 :         kap = s%atm_structure(atm_kap,k)
     346            0 :         kap_rho = s%atm_structure(atm_dlnkap_dlnd,k)
     347            0 :         kap_T = s%atm_structure(atm_dlnkap_dlnT,k)
     348            0 :         kap_ad = nabla_ad*kap_T + kap_rho/Gamma_1
     349            0 :         kap_S = kap_T - delta*kap_rho
     350              : 
     351            0 :         eps = 0d0
     352            0 :         eps_ad = 0d0
     353            0 :         eps_S = 0d0
     354              : 
     355            0 :         g = s%cgrav(1)*m/(r*r)
     356            0 :         N2 = g*g*(rho/P)*delta*(nabla_ad - nabla)
     357            0 :         L2_ll1 = Gamma_1*P/(rho*r**2)
     358            0 :         P_scale = P/(rho*g)
     359              : 
     360            0 :         V = rho*g*r/P
     361            0 :         V_g = V/Gamma_1
     362            0 :         As = N2*r/g
     363            0 :         U = pi4*rho*r**3/m
     364              : 
     365            0 :         l_rad(j) = l
     366              : 
     367            0 :         c_1 = (r/R_star)**3*(M_star/m)
     368            0 :         c_2 = (kap_ad - 4d0*nabla_ad)*V*nabla  ! Note -- we omit the nabla_ad*(dnabla_ad + V) term for now
     369            0 :         c_3 = 0d0
     370            0 :         c_4 = pi4*r**3*rho*T*c_P/l_rad(j)*SQRT(s%cgrav(1)*M_star/R_star**3)
     371              : 
     372              :       end associate
     373              : 
     374              : 
     375            0 :       return
     376              : 
     377              :     end subroutine store_point_data_atm
     378              : 
     379              : 
     380            0 :     subroutine store_point_data_env (j, k)
     381              : 
     382              :       integer, intent(in) :: j
     383              :       integer, intent(in) :: k
     384              : 
     385            0 :       real(dp) :: rho
     386            0 :       real(dp) :: P
     387            0 :       real(dp) :: T
     388            0 :       real(dp) :: kap_rho
     389            0 :       real(dp) :: kap_T
     390            0 :       real(dp) :: kap_ad
     391            0 :       real(dp) :: eps
     392            0 :       real(dp) :: eps_rho
     393            0 :       real(dp) :: eps_T
     394              : 
     395              :       ! Store data associated with envelope face k into the point_data
     396              :       ! array at position j
     397              : 
     398              :       ! Store data associated with atmosphere point k into the
     399              :       ! point_data array at position j
     400              : 
     401              :       associate ( &
     402              :            m => point_data(1,j), &
     403              :            logrho => point_data(2,j) , &
     404              :            logP => point_data(3,j), &
     405              :            logT => point_data(4,j), &
     406              :            r => point_data(5,j), &
     407              :            V_g => point_data(6,j), &
     408              :            As => point_data(7,j), &
     409              :            U => point_data(8,j), &
     410              :            c_1 => point_data(9,j), &
     411              :            N2 => point_data(10,j), &
     412              :            L2_ll1 => point_data(11,j), &
     413              :            g => point_data(12,j), &
     414              :            l => point_data(13,j), &
     415              :            V => point_data(14,j), &
     416              :            nabla_ad => point_data(15,j), &
     417              :            nabla => point_data(16,j), &
     418              :            C_P => point_data(17,j), &
     419              :            delta => point_data(18,j), &
     420              :            kap_S => point_data(19,j), &
     421              :            eps_ad => point_data(20,j), &
     422              :            eps_S => point_data(21,j), &
     423              :            c_3 => point_data(23,j), &
     424              :            c_4 => point_data(24,j), &
     425              :            P_scale => point_data(26,j), &
     426              :            Gamma_1 => point_data(29,j), &
     427              :            entropy => point_data(30,j), &
     428              :            kap => point_data(31,j), &
     429              :            chi_rho => point_data(32,j), &
     430              :            chi_T => point_data(33,j), &
     431              :            c_2 => point_data(35,j))
     432              : 
     433            0 :         m = s%m_grav(k)
     434            0 :         r = s%r(k)
     435            0 :         l = s%L(k)
     436              : 
     437            0 :         if (s%interpolate_rho_for_pulse_data) then
     438            0 :            rho = eval_face(s%dq, s%rho, k, 1, s%nz)
     439              :         else
     440            0 :            rho = eval_face_rho(s, k, 1, s%nz)
     441              :         end if
     442            0 :         P = eval_face(s%dq, s%Peos, k, 1, s%nz)
     443            0 :         T = eval_face(s%dq, s%T, k, 1, s%nz)
     444              : 
     445            0 :         logrho = log10(rho)
     446            0 :         logP = log10(P)
     447            0 :         logT = log10(T)
     448              : 
     449            0 :         nabla_ad = eval_face(s%dq, s%grada, k, 1, s%nz)
     450            0 :         nabla = s%gradT(k)
     451            0 :         C_P = eval_face(s%dq, s%cp, k, 1, s%nz)
     452            0 :         delta = eval_face(s%dq, s%chiT, k, 1, s%nz)/eval_face(s%dq, s%chiRho, k, 1, s%nz)
     453            0 :         Gamma_1 = eval_face(s%dq, s%gamma1, k, 1, s%nz)
     454            0 :         entropy = exp(eval_face(s%dq, s%lnS, k, 1, s%nz))
     455            0 :         chi_rho = eval_face(s%dq, s%chiRho, k, 1, s%nz)
     456            0 :         chi_T = eval_face(s%dq, s%chiT, k, 1, s%nz)
     457              : 
     458            0 :         kap = eval_face(s%dq, s%opacity, k, 1, s%nz)
     459            0 :         kap_rho = eval_face(s%dq, s%d_opacity_dlnd, k, 1, s%nz)/kap
     460            0 :         kap_T = eval_face(s%dq, s%d_opacity_dlnT, k, 1, s%nz)/kap
     461            0 :         kap_ad = nabla_ad*kap_T + kap_rho/Gamma_1
     462            0 :         kap_S = kap_T - delta*kap_rho
     463              : 
     464            0 :         eps = eval_face(s%dq, s%eps_nuc, k, 1, s%nz)
     465            0 :          if (ABS(eps) > 1D-99) then
     466            0 :            eps_rho = eval_face(s%dq, s%d_epsnuc_dlnd, k, 1, s%nz)/eps
     467            0 :            eps_T = eval_face(s%dq, s%d_epsnuc_dlnT, k, 1, s%nz)/eps
     468              :         else
     469              :            eps_rho = 0d0
     470              :            eps_T = 0d0
     471              :         end if
     472            0 :         eps_ad = nabla_ad*eps_T + eps_rho/Gamma_1
     473            0 :         eps_S = eps_T - delta*eps_rho
     474              : 
     475            0 :         g = s%grav(k)
     476            0 :         N2 = eval_face_A_ast(s, k, 1, s%nz)*g/r
     477            0 :         L2_ll1 = Gamma_1*P/(rho*r**2)
     478            0 :         P_scale = s%scale_height(k)
     479              : 
     480            0 :         V = rho*g*r/P
     481            0 :         V_g = V/Gamma_1
     482            0 :         As = N2*r/g
     483            0 :         U = pi4*rho*r**3/m
     484              : 
     485            0 :         l_rad(j) = 16d0*pi*r*crad*clight*T**4*nabla*V/(3d0*kap*rho)
     486              : 
     487            0 :         c_1 = (r/R_star)**3*(M_star/m)
     488            0 :         c_2 = (kap_ad - 4d0*nabla_ad)*V*nabla  ! Note -- we omit the nabla_ad*(dnabla_ad + V) term for now
     489            0 :         c_3 = pi4*r**3*rho*eps/l_rad(j)
     490            0 :         c_4 = pi4*r**3*rho*T*c_P/l_rad(j)*SQRT(s%cgrav(1)*M_star/R_star**3)
     491              : 
     492              :       end associate
     493              : 
     494              : 
     495            0 :       return
     496              : 
     497              :     end subroutine store_point_data_env
     498              : 
     499              : 
     500            0 :     subroutine store_point_data_ctr (j)
     501              : 
     502              :       integer, intent(in) :: j
     503              : 
     504            0 :       real(dp) :: rho
     505            0 :       real(dp) :: P
     506            0 :       real(dp) :: T
     507            0 :       real(dp) :: kap_rho
     508            0 :       real(dp) :: kap_T
     509            0 :       real(dp) :: kap_ad
     510            0 :       real(dp) :: eps
     511            0 :       real(dp) :: eps_rho
     512            0 :       real(dp) :: eps_T
     513            0 :       real(dp) :: cgrav
     514              : 
     515              :       ! Store data for the center into the point_data array at position j
     516              : 
     517              :       associate ( &
     518              :            m => point_data(1,j), &
     519              :            logrho => point_data(2,j) , &
     520              :            logP => point_data(3,j), &
     521              :            logT => point_data(4,j), &
     522              :            r => point_data(5,j), &
     523              :            V_g => point_data(6,j), &
     524              :            As => point_data(7,j), &
     525              :            U => point_data(8,j), &
     526              :            c_1 => point_data(9,j), &
     527              :            N2 => point_data(10,j), &
     528              :            L2_ll1 => point_data(11,j), &
     529              :            g => point_data(12,j), &
     530              :            l => point_data(13,j), &
     531              :            V => point_data(14,j), &
     532              :            nabla_ad => point_data(15,j), &
     533              :            nabla => point_data(16,j), &
     534              :            C_P => point_data(17,j), &
     535              :            delta => point_data(18,j), &
     536              :            kap_S => point_data(19,j), &
     537              :            eps_ad => point_data(20,j), &
     538              :            eps_S => point_data(21,j), &
     539              :            c_3 => point_data(23,j), &
     540              :            c_4 => point_data(24,j), &
     541              :            P_scale => point_data(26,j), &
     542              :            Gamma_1 => point_data(29,j), &
     543              :            entropy => point_data(30,j), &
     544              :            kap => point_data(31,j), &
     545              :            chi_rho => point_data(32,j), &
     546              :            chi_T => point_data(33,j), &
     547              :            c_2 => point_data(35,j))
     548              : 
     549            0 :         m = 0d0
     550            0 :         r = 0d0
     551            0 :         l = 0d0
     552              : 
     553            0 :         if (s%interpolate_rho_for_pulse_data) then
     554            0 :            rho = eval_center(s%rmid, s%rho, 1, s%nz)
     555              :         else
     556            0 :            rho = eval_center_rho(s, s%nz)
     557              :         end if
     558            0 :         P = eval_center(s%rmid, s%Peos, 1, s%nz)
     559            0 :         T = eval_center(s%rmid, s%T, 1, s%nz)
     560              : 
     561            0 :         logrho = log10(rho)
     562            0 :         logP = log10(P)
     563            0 :         logT = log10(T)
     564              : 
     565            0 :         nabla_ad = eval_center(s%rmid, s%grada, 1, s%nz)
     566            0 :         nabla = eval_center(s%r, s%gradT, 1, s%nz)
     567            0 :         C_P = eval_center(s%rmid, s%cp, 1, s%nz)
     568            0 :         delta = eval_center(s%rmid, s%chiT, 1, s%nz)/eval_center(s%rmid, s%chiRho, 1, s%nz)
     569            0 :         Gamma_1 = eval_center(s%rmid, s%gamma1, 1, s%nz)
     570            0 :         entropy = exp(eval_center(s%rmid, s%lnS, 1, s%nz))
     571            0 :         chi_rho = eval_center(s%rmid, s%chiRho, 1, s%nz)
     572            0 :         chi_T = eval_center(s%rmid, s%chiT, 1, s%nz)
     573              : 
     574            0 :         kap = eval_center(s%rmid, s%opacity, 1, s%nz)
     575            0 :         kap_rho = eval_center(s%rmid, s%d_opacity_dlnd, 1, s%nz)/kap
     576            0 :         kap_T = eval_center(s%rmid, s%d_opacity_dlnT, 1, s%nz)/kap
     577            0 :         kap_ad = nabla_ad*kap_T + kap_rho/Gamma_1
     578            0 :         kap_S = kap_T - delta*kap_rho
     579              : 
     580            0 :         eps = eval_center(s%rmid, s%eps_nuc, 1, s%nz)
     581            0 :         if (ABS(eps) > 1D-99) then
     582            0 :            eps_rho = eval_center(s%rmid, s%d_epsnuc_dlnd, 1, s%nz)/eps
     583            0 :            eps_T = eval_center(s%rmid, s%d_epsnuc_dlnT, 1, s%nz)/eps
     584              :         else
     585              :            eps_rho = 0d0
     586              :            eps_T = 0d0
     587              :         end if
     588            0 :         eps_ad = nabla_ad*eps_T + eps_rho/Gamma_1
     589            0 :         eps_S = eps_T - delta*eps_rho
     590              : 
     591            0 :         g = 0d0
     592            0 :         N2 = 0d0
     593            0 :         L2_ll1 = HUGE(0d0)
     594            0 :         P_scale = eval_center(s%r, s%scale_height, 1, s%nz)
     595              : 
     596            0 :         V = 0d0
     597            0 :         V_g = 0d0
     598            0 :         As = 0d0
     599            0 :         U = 3d0
     600              : 
     601            0 :         l_rad(j) = 0d0
     602              : 
     603            0 :         cgrav = eval_center(s%r, s%cgrav, 1, s%nz)
     604              : 
     605            0 :         c_1 = 3d0*(M_star/R_star**3)/(pi4*rho)
     606            0 :         c_2 = 0d0
     607            0 :         c_3 = 9d0*eps*kap*P/(16*pi*crad*clight*T**4*nabla*cgrav)
     608            0 :         c_4 = 9d0*T*c_P*kap*P/(16*pi*crad*clight*T**4*nabla*cgrav)*SQRT(s%cgrav(s%nz)*M_star/R_star**3)
     609              : 
     610              :       end associate
     611              : 
     612              : 
     613            0 :       return
     614              : 
     615              :     end subroutine store_point_data_ctr
     616              : 
     617              : 
     618            0 :     function log_deriv (x, y, dy_a, dy_b) result (dy)
     619              : 
     620              :       real(dp), intent(in)           :: x(:)
     621              :       real(dp), intent(in)           :: y(:)
     622              :       real(dp), intent(in), optional :: dy_a
     623              :       real(dp), intent(in), optional :: dy_b
     624              :       real(dp)                       :: dy(SIZE(x))
     625              : 
     626              :       integer :: n
     627              :       integer :: j
     628              : 
     629              :       ! Evaluate the logarithmic derivative of y wrt x, using simple
     630              :       ! finite differences
     631              : 
     632            0 :       n = SIZE(x)
     633              : 
     634            0 :       if (PRESENT(dy_a)) then
     635            0 :          dy(1) = dy_a
     636              :       else
     637            0 :          dy(1) = x(1)/y(1) * (y(2) - y(1))/(x(2) - x(1))
     638              :       end if
     639              : 
     640            0 :       do j = 2, n-1
     641            0 :          dy(j) = x(j)/y(j) * (y(j+1) - y(j-1))/(x(j+1) - x(j-1))
     642              :       end do
     643              : 
     644            0 :       if (PRESENT(dy_b)) then
     645            0 :          dy(n) = dy_b
     646              :       else
     647            0 :          dy(n) = x(n)/y(n) * (y(n) - y(n-1))/(x(n) - x(n-1))
     648              :       end if
     649              : 
     650            0 :       return
     651              : 
     652              :     end function log_deriv
     653              : 
     654              :   end subroutine get_cafein_data
     655              : 
     656              : 
     657            0 :   subroutine write_cafein_data (id, filename, global_data, point_data, ierr)
     658              : 
     659              :     integer, intent(in)      :: id
     660              :     character(*), intent(in) :: filename
     661              :     real(dp), intent(in)     :: global_data(:)
     662              :     real(dp), intent(in)     :: point_data(:,:)
     663              :     integer, intent(out)     :: ierr
     664              : 
     665              :     integer :: iounit
     666              :     integer :: nn
     667              :     integer :: j
     668              : 
     669              :     ! Write CAFein data to file
     670              : 
     671              :     ! Open the file
     672              : 
     673            0 :     open(newunit=iounit, file=TRIM(filename), status='REPLACE', iostat=ierr)
     674            0 :     if (ierr /= 0) then
     675            0 :        write(*,*) 'failed to open '//TRIM(filename)
     676            0 :        return
     677              :     end if
     678              : 
     679              :     ! Write the data
     680              : 
     681            0 :     nn = SIZE(point_data, 2)
     682              : 
     683              :     write(iounit, 100) &
     684              :          '..................M(Msun)' // '..................R(Rsun)' // '..................L(Lsun)' // &
     685              :          '..............Pc(erg/cm3)' // '....................Tc(K)' // '..............rhoC(g/cm3)' // &
     686              :          '..................Teff(K)' // '................sec_units' // '..............grams_units' // &
     687              :          '.................cm_units' // '................erg_units' // '..................K_units' // &
     688            0 :          '...................unused'
     689              : 100 format(A)
     690              : 
     691            0 :     write(iounit, 110) global_data
     692              : 110 format(13(1X,E24.14E3))
     693              : 
     694            0 :     write(iounit, *)
     695              :     write(iounit, 100) &
     696              :          '........................m' // '...................logrho' // '.....................logP' // &
     697              :          '.....................logT' // '........................r' // '.......................Vg' // &
     698              :          '....................Astar' // '........................U' // '.......................c1' // &
     699              :          '.......................N2' // '..............L2/(l(l+1))' // '........................g' // &
     700              :          '.......................Lr' // '........................V' // '............del_ad(noDim)' // &
     701              :          '...............del(noDim)' // '.......................Cp' // '......................v_t' // &
     702              :          '...........kappa_s(noDim)' // '............eps_ad(noDim)' // '.............eps_s(noDim)' // &
     703              :          '................c2_fitted' // '.......................c3' // '.......................c4' // &
     704              :          '...............dlnLr/dlnr' // '..................P_scale' // '........StartRadSurfLayer' // &
     705              :          '..........EndRadSurfLayer' // '...................Gamma1' // '..................entropy' // &
     706              :          '....................kappa' // '...................chiRho' // '.....................chiT' // &
     707            0 :          '..................U/Usurf' // '.......................c2'
     708              : 
     709            0 :     do j = 1, nn
     710            0 :        write(iounit, 120) point_data(:,j)
     711              : 120    format(35(1X,E24.14E3))
     712              :     end do
     713              : 
     714              :     ! Close the file
     715              : 
     716            0 :     close(iounit)
     717              : 
     718            0 :     return
     719              : 
     720              :   end subroutine write_cafein_data
     721              : 
     722              : end module pulse_cafein
        

Generated by: LCOV version 2.0-1