def eval_baryon_density(self, p):
     if isinstance(p, list) or isinstance(p, np.ndarray):    
         rho = np.zeros(len(p))  
         for i, pres in enumerate(p):
             rho [i] = lalsim.SimNeutronStarEOSRestMassDensityOfPseudoEnthalpy(
                 lalsim.SimNeutronStarEOSPseudoEnthalpyOfPressure(pres,self.eos), self.eos)    
     else:
         rho  = lalsim.SimNeutronStarEOSRestMassDensityOfPseudoEnthalpy(
             lalsim.SimNeutronStarEOSPseudoEnthalpyOfPressure(p,self.eos), self.eos) 
     return rho
Exemple #2
0
 def eval_speed_of_sound(self, p):
     if isinstance(p, list) or isinstance(p, np.ndarray):
         cs = np.zeros(len(p))
         for i, pres in enumerate(p):
             try:
                 h = lalsim.SimNeutronStarEOSPseudoEnthalpyOfPressure(
                     pres, self.eos)
                 cs[i] = lalsim.SimNeutronStarEOSSpeedOfSound(h, self.eos)
             except:
                 print(pres, "failed to produce a valid sound speed")
                 break
     else:
         h = lalsim.SimNeutronStarEOSPseudoEnthalpyOfPressure(p, self.eos)
         cs = lalsim.SimNeutronStarEOSSpeedOfSound(h, self.eos)
     return cs
def lal_inf_eos_physical_check(gammas, verbose=False):
    '''
    Python version of LALInferenceEOSPhysicalCheck:
    https://lscsoft.docs.ligo.org/lalsuite/lalinference/_l_a_l_inference_8c_source.html#l02404
    '''

    # apply 0.6 < Gamma(p) < 4.5 constraint
    if not lalinf_sd_gamma_check(gammas):

        return False

    else:

        # create LAL EOS object
        eos = lalsim.SimNeutronStarEOS4ParameterSpectralDecomposition(*gammas)

        # ensure mass turnover doesn't happen too soon
        mdat_prev = 0.0
        logpmin = 75.5
        logpmax = np.log(lalsim.SimNeutronStarEOSMaxPressure(eos))
        dlogp = (logpmax - logpmin) / 100.0
        for j in range(4):

            # determine if maximum mass has been found
            pdat = np.exp(logpmin + j * dlogp)
            rdat, mdat, kdat = lalsim.SimNeutronStarTOVODEIntegrate(pdat, eos)
            if mdat <= mdat_prev:
                if verbose:
                    print('rejecting: too few EOS points', gammas)
                return False
            mdat_prev = mdat

        # make EOS family, and calculate speed of sound and max
        # and min mass allowed by EOS
        fam = lalsim.CreateSimNeutronStarFamily(eos)
        min_mass_kg = lalsim.SimNeutronStarFamMinimumMass(fam)
        max_mass_kg = lalsim.SimNeutronStarMaximumMass(fam)
        pmax = lalsim.SimNeutronStarCentralPressure(max_mass_kg, fam)
        hmax = lalsim.SimNeutronStarEOSPseudoEnthalpyOfPressure(pmax, eos)
        vsmax = lalsim.SimNeutronStarEOSSpeedOfSoundGeometerized(hmax, eos)

        # apply constraints on speed of sound and maximum mass
        if vsmax > c_s_max:
            if verbose:
                print('rejecting:', \
                      'sound speed {:4.2f} too high'.format(vsmax), \
                      gammas)
            return False
        if max_mass_kg < ns_mass_max_kg:
            if verbose:
                print('rejecting:', \
                      'max NS mass {:4.2f} too low'.format(max_mass_kg / m_sol_kg), \
                      gammas)
            return False

        return True
Exemple #4
0
    def test_speed_of_sound_causal(self,
                                   test_only_under_mmax=True,
                                   fast_test=True):
        """
        Test if EOS satisfies speed of sound.
        Relies on low-level lalsimulation interpolation routines to get v(h) and as such is not very reliable

        By DEFAULT, we are testing the part of the EOS that is
             - at the largest pressure (assuming monotonic sound speed)
             - associated with the maximum mass NS that is stable
        We can also test the full table that is provided to us.
        https://git.ligo.org/lscsoft/lalsuite/blob/lalinference_o2/lalinference/src/LALInference.c#L2513
        """
        npts_internal = 1000
        eos = self.eos
        fam = self.eos_fam
        # Largest NS provides largest attained central pressure
        m_max_SI = self.mMaxMsun * lal.MSUN_SI
        if not test_only_under_mmax:
            hmax = lalsim.SimNeutronStarEOSMaxPseudoEnthalpy(eos)
        else:
            try:
                pmax = lalsim.SimNeutronStarCentralPressure(m_max_SI, fam)
                hmax = lalsim.SimNeutronStarEOSPseudoEnthalpyOfPressure(
                    pmax, eos)
            except:
                # gatch gsl interpolation errors for example
                return False
        if fast_test:
            # https://git.ligo.org/lscsoft/lalsuite/blob/lalinference_o2/lalinference/src/LALInference.c#L2513
            try:
                vsmax = lalsim.SimNeutronStarEOSSpeedOfSoundGeometerized(
                    hmax, eos)
                return vsmax < 1.1
            except:
                # catch gsl interpolation errors for example
                return False
        else:
            if rosDebug:
                print(" performing comprehensive test ")
        h = np.linspace(0.0001, hmax, npts_internal)
        #        h = np.linspace(0.0001,lalsim.SimNeutronStarEOSMinAcausalPseudoEnthalpy(eos),npts_internal)
        vs_internal = np.zeros(npts_internal)
        for indx in np.arange(npts_internal):
            vs_internal[
                indx] = lalsim.SimNeutronStarEOSSpeedOfSoundGeometerized(
                    h[indx], eos)
            if rosDebug:
                print(h[indx], vs_internal[indx])
        return not np.any(
            vs_internal > 1.1)  # allow buffer, so we have some threshold
Exemple #5
0
 def is_causal(self):
     p_max = lalsim.SimNeutronStarEOSMaxPressure(self.eos)
     c_s_max = lalsim.SimNeutronStarEOSSpeedOfSound(
         lalsim.SimNeutronStarEOSPseudoEnthalpyOfPressure(p_max, self.eos),
         self.eos)
     return c_s_max < c / 100 * 1.1  # Conversion from cgs to SI (leave some leeway like in 1805.11217)