Example #1
0
def func_get_time(M1, M2, t_obs):
    """ Get the adjusted time for a secondary that accreted
    the primary's envelope in thermal timescale MT

    parameters
    ----------
    M1 : float
        Primary mass before mass transfer (Msun)
    M2 : float
        Secondary mass before mass transfer (Msun)
    t_obs : float
        Observation time (Myr)

    Returns
    -------
    Effective observed time: float
        Time to be fed into load_sse.py function func_get_sse_star() (Myr)
    """

    t_lifetime_1 = load_sse.func_sse_ms_time(M1)
    he_mass_1 = load_sse.func_sse_he_mass(M1)

    t_lifetime_2 = load_sse.func_sse_ms_time(M2)
    he_mass_2 = load_sse.func_sse_he_mass(M2)

    # Relative lifetime through star 2 at mass gain
    he_mass = t_lifetime_1/t_lifetime_2 * he_mass_2

    # Get new secondary parameters
    mass_new = M2 + M1 - he_mass_1
    t_lifetime_new = load_sse.func_sse_ms_time(mass_new)
    he_mass_new = load_sse.func_sse_he_mass(mass_new)

    # New, effective lifetime
    t_eff = he_mass / he_mass_new * t_lifetime_new

    # Now, we obtain the "effective observed time"
    return t_eff + t_obs - t_lifetime_1
Example #2
0
def full_forward(M1, M2, A, ecc, v_k, theta, phi, t_obs):
    """ Evolve a binary forward from its initial conditions

    Parameters
    ----------
    M1 : float
        Initial primary mass (Msun)
    M2 : float
        Initial secondary mass (Msun)
    A : float
        Initial orbital separation (Rsun)
    ecc : float
        Initial orbital eccentricity (unitless)
    v_k : float
        SN kick velocity
    theta : float
        SN kick polar angle
    phi : float
        SN kick azimuthal angle
    t_obs : float
        observation time

    Returns
    -------
    M_NS : float or ndarray
        Array of final primary masses (Currently set to the NS mass, c.M_NS)
    M_2 : float or ndarray
        Array of final secondary masses (Msun)
    L_x : float or ndarray
        X-ray luminosity (erg/s)
    v_sys : float or ndarray
        Systemic velocity (km/s)
    M2_dot : float or ndarray
        Mass accretion rate (Msun/yr)
    A : float or ndarray
        Orbital separation (Rsun)
    ecc : float or ndarray
        Orbital eccentricity (unitless)
    theta : float or ndarray
        Projected angular distance traveled from birth location (radians)
    k_type : int
        k-type of HMXB donor
    """

    if load_sse.func_sse_mass is None:
        load_sse.load_sse()


    if isinstance(M1, np.ndarray):
        dtypes = [('M_NS','<f8'), \
                ('M_2','<f8'), \
                ('L_x','<f8'), \
                ('v_sys','<f8'), \
                ('M2_dot','<f8'), \
                ('A','<f8'), \
                ('ecc','<f8'), \
                ('theta','<f8'), \
                ('k_type','<i8')]

        HMXB = np.recarray(len(M1), dtype=dtypes)

        for i in np.arange(len(M1)):

            if isinstance(t_obs, np.ndarray):
                if t_obs[i] < load_sse.func_sse_ms_time(M1[i]):
                    HMXB["M_NS"][i] = M1[i]
                    HMXB["M_2"][i] = M2[i]
                    HMXB["A"][i] = A[i]
                    continue
            else:
                if t_obs < load_sse.func_sse_ms_time(M1[i]):
                    HMXB["M_NS"][i] = M1[i]
                    HMXB["M_2"][i] = M2[i]
                    HMXB["A"][i] = A[i]
                    continue


            # First MT phase
            M_1_b, M_2_b, A_b = binary_evolve.func_MT_forward(M1[i], M2[i], A[i], ecc[i])

            if isinstance(t_obs, np.ndarray):
                if t_obs[i] < load_sse.func_sse_tmax(M1[i]):
                    HMXB["M_NS"][i] = M_1_b
                    HMXB["M_2"][i] = M_2_b
                    HMXB["A"][i] = A_b
                    continue
            else:
                if t_obs < load_sse.func_sse_tmax(M1[i]):
                    HMXB["M_NS"][i] = M_1_b
                    HMXB["M_2"][i] = M_2_b
                    HMXB["A"][i] = A_b
                    continue


            # SN
            A_tmp, v_sys_tmp, e_tmp = binary_evolve.func_SN_forward(M_1_b, M_2_b, A_b, v_k[i], theta[i], phi[i])

            # XRB
            if isinstance(t_obs, np.ndarray):
                M_2_tmp, L_x_tmp, M2_dot_out, A_out = binary_evolve.func_Lx_forward(M1[i], M2[i], M_2_b, A_tmp, e_tmp, t_obs[i])
                theta_out = (t_obs[i] - load_sse.func_sse_tmax(M1[i])) * v_sys_tmp / c.dist_SMC * c.yr_to_sec * 1.0e6 * np.sin(get_theta(1))
                tobs_eff = binary_evolve.func_get_time(M1[i], M2[i], t_obs[i])
            else:
                M_2_tmp, L_x_tmp, M2_dot_out, A_out = binary_evolve.func_Lx_forward(M1[i], M2[i], M_2_b, A_tmp, e_tmp, t_obs)
                theta_out = (t_obs - load_sse.func_sse_tmax(M1[i])) * v_sys_tmp / c.dist_SMC * c.yr_to_sec * 1.0e6 * np.sin(get_theta(1))
                tobs_eff = binary_evolve.func_get_time(M1[i], M2[i], t_obs)

            # To get k-type of HMXB donor
            if M_2_b > c.max_mass:
                k_type = -999
            else:
                M_tmp, M_dot_tmp, R_tmp, k_type = load_sse.func_get_sse_star(M_2_b, tobs_eff)


            HMXB["M_NS"][i] = c.M_NS
            HMXB["M_2"][i] = M_2_tmp
            HMXB["L_x"][i] = L_x_tmp
            HMXB["v_sys"][i] = v_sys_tmp
            HMXB["M2_dot"][i] = M2_dot_out
            HMXB["A"][i] = A_out
            HMXB["ecc"][i] = e_tmp
            HMXB["theta"][i] = theta_out
            HMXB["k_type"][i] = int(k_type)


        return HMXB["M_NS"], HMXB["M_2"], HMXB["L_x"], HMXB["v_sys"], HMXB["M2_dot"], HMXB["A"], HMXB["ecc"], HMXB["theta"], HMXB["k_type"]

    else:

        # Star does not make it to MT phase
        if t_obs < load_sse.func_sse_ms_time(M1): return M1, M2, 0.0, 0.0, 0.0, A, ecc, 0.0

        # MT phase
        M_1_b, M_2_b, A_b = binary_evolve.func_MT_forward(M1, M2, A, ecc)

        # Star does not make it to SN
        if t_obs < load_sse.func_sse_tmax(M1): return M_1_b, M_2_b, 0.0, 0.0, 0.0, A_b, ecc, 0.0

        # SN
        A_tmp, v_sys_tmp, e_tmp = binary_evolve.func_SN_forward(M_1_b, M_2_b, A_b, v_k, theta, phi)

        # XRB
        M_2_tmp, L_x_tmp, M2_dot_out, A_out = binary_evolve.func_Lx_forward(M1, M2, M_2_b, A_tmp, e_tmp, t_obs)

        theta_out = (t_obs - load_sse.func_sse_tmax(M1)) * v_sys_tmp / c.dist_SMC * c.yr_to_sec * 1.0e6 * np.sin(get_theta(1))

        # To get k-type of HMXB donor
        tobs_eff = binary_evolve.func_get_time(M1, M2, t_obs)
        M_tmp, M_dot_tmp, R_tmp, k_type = load_sse.func_get_sse_star(M_2_b, tobs_eff)

        return c.M_NS, M_2_tmp, L_x_tmp, v_sys_tmp, M2_dot_out, A_out, e_tmp, theta_out, int(k_type)