Esempio n. 1
0
def integrate_ion_recomb_collapse(z, coeff_ion,
                                  temp_min = 1e4,
                                  passed_min_mass = False,
                                  temp_gas=1e4, 
                                  alpha_B=None,
                                  clump_fact_func = clumping_factor_BKP,
                                  **cosmo):  

    """IGM ionization state with recombinations from halo collapse
    fraction. Integrates an ODE describing IGM ionization and
    recombination rates.

    z: array 

       The redshift values at which to calculate the ionized
       fraction. This array should be in reverse numerical order. The
       first redshift specified should be early enough that the
       universe is still completely neutral.

    coeff_ion: 

       The coefficient converting the collapse fraction to ionized
       fraction, neglecting recombinations. Equivalent to the product
       (f_star * f_esc_gamma * N_gamma) in the BKP paper.


    temp_min: 

       See docs for ionization_from_collapse. Either the minimum virial
       temperature or minimum mass of halos contributing to
       reionization.

    passed_temp_min: 

       See documentation for ionization_from_collapse.

    temp_gas: 

       Gas temperature used to calculate the recombination coefficient
       if alpha_b is not specified.

    alpha_B:

       Optional recombination coefficient in units of cm^3
       s^-1. In alpha_B=None, it is calculated from temp_gas.

    clump_fact_func: function

      Function returning the clumping factor when given a redshift.

   cosmo: dict

      Dictionary specifying the cosmological parameters.

    We assume, as is fairly standard, that the ionized
    fraction is contained in fully ionized bubbles surrounded by a
    fully neutral IGM. The output is therefore the volume filling
    factor of ionized regions, not the ionized fraction of a
    uniformly-ionized IGM.

    I have also made the standard assumption that all ionized photons
    are immediately absorbed, which allows the two differential
    equations (one for ionization-recombination and one for
    emission-photoionizaion) to be combined into a single ODE.

    """

    # Determine recombination coefficient.
    if alpha_B is None:
        alpha_B_cm = recomb_rate_coeff_HG(temp_gas, 'H', 'B')
    else:
        alpha_B_cm = alpha_B
    alpha_B = alpha_B_cm / (cc.Mpc_cm**3.)
    print ("Recombination rate alpha_B = %.4g (Mpc^3 s^-1) = %.4g (cm^3 s^-1)" 
           % (alpha_B, alpha_B_cm))

    # Normalize power spectrum.
    if 'deltaSqr' not in cosmo:
        cosmo['deltaSqr'] = cp.norm_power(**cosmo)

    # Calculate useful densities.
    rho_crit, rho_0, n_He_0, n_H_0 = cden.baryon_densities(**cosmo)

    # Function used in the integration.
    # Units: (Mpc^3 s^-1) * Mpc^-3 = s^-1
    coeff_rec_func = lambda z: (clump_fact_func(z)**2. * 
                                alpha_B * 
                                n_H_0 * (1.+z)**3.)

    # Generate a function that converts redshift to age of the universe.
    redfunc = cd.quick_redshift_age_function(zmax = 1.1 * numpy.max(z), 
                                              zmin = -0.0,
                                              **cosmo)
    # Function used in the integration.
    ionfunc = quick_ion_col_function(coeff_ion, 
                                     temp_min, 
                                     passed_min_mass = passed_min_mass,
                                     zmax = 1.1 * numpy.max(z), 
                                     zmin = -0.0, 
                                     zstep = 0.1, **cosmo)

    # Convert specified redshifts to cosmic time (age of the universe).
    t = cd.age(z, **cosmo)

    # Integrate to find u(z) = x(z) - w(z), where w is the ionization fraction 
    u = si.odeint(_udot, y0=0.0, t=t,
                  args=(coeff_rec_func, redfunc, ionfunc))
    u = u.flatten()

    w = ionization_from_collapse(z, coeff_ion, temp_min, 
                                 passed_min_mass = passed_min_mass,
                                 **cosmo)
    x = u + w
    x[x > 1.0] = 1.0
    return x, w, t
def integrate_ion_recomb_collapse(z, coeff_ion,
                                  temp_min = 1e4,
                                  passed_min_mass = False,
                                  temp_gas=1e4, 
                                  alpha_B=None,
                                  clump_fact_func = clumping_factor_BKP,
                                  **cosmo):  

    """IGM ionization state with recombinations from halo collapse
    fraction. Integrates an ODE describing IGM ionization and
    recombination rates.

    z: array 

       The redshift values at which to calculate the ionized
       fraction. This array should be in reverse numerical order. The
       first redshift specified should be early enough that the
       universe is still completely neutral.

    coeff_ion: 

       The coefficient converting the collapse fraction to ionized
       fraction, neglecting recombinations. Equivalent to the product
       (f_star * f_esc_gamma * N_gamma) in the BKP paper.


    temp_min: 

       See docs for ionization_from_collapse. Either the minimum virial
       temperature or minimum mass of halos contributing to
       reionization.

    passed_temp_min: 

       See documentation for ionization_from_collapse.

    temp_gas: 

       Gas temperature used to calculate the recombination coefficient
       if alpha_b is not specified.

    alpha_B:

       Optional recombination coefficient in units of cm^3
       s^-1. In alpha_B=None, it is calculated from temp_gas.

    clump_fact_func: function

      Function returning the clumping factor when given a redshift.

   cosmo: dict

      Dictionary specifying the cosmological parameters.

    We assume, as is fairly standard, that the ionized
    fraction is contained in fully ionized bubbles surrounded by a
    fully neutral IGM. The output is therefore the volume filling
    factor of ionized regions, not the ionized fraction of a
    uniformly-ionized IGM.

    I have also made the standard assumption that all ionized photons
    are immediately absorbed, which allows the two differential
    equations (one for ionization-recombination and one for
    emission-photoionizaion) to be combined into a single ODE.

    """

    # Determine recombination coefficient.
    if alpha_B is None:
        alpha_B_cm = recomb_rate_coeff_HG(temp_gas, 'H', 'B')
    else:
        alpha_B_cm = alpha_B
    alpha_B = alpha_B_cm / (cc.Mpc_cm**3.)
    print ("Recombination rate alpha_B = %.4g (Mpc^3 s^-1) = %.4g (cm^3 s^-1)" 
           % (alpha_B, alpha_B_cm))

    # Normalize power spectrum.
    if 'deltaSqr' not in cosmo:
        cosmo['deltaSqr'] = cp.norm_power(**cosmo)

    # Calculate useful densities.
    rho_crit, rho_0, n_He_0, n_H_0 = cden.baryon_densities(**cosmo)

    # Function used in the integration.
    # Units: (Mpc^3 s^-1) * Mpc^-3 = s^-1
    coeff_rec_func = lambda z: (clump_fact_func(z)**2. * 
                                alpha_B * 
                                n_H_0 * (1.+z)**3.)

    # Generate a function that converts redshift to age of the universe.
    redfunc = cd.quick_redshift_age_function(zmax = 1.1 * numpy.max(z), 
                                              zmin = -0.0,
                                              **cosmo)
    # Function used in the integration.
    ionfunc = quick_ion_col_function(coeff_ion, 
                                     temp_min, 
                                     passed_min_mass = passed_min_mass,
                                     zmax = 1.1 * numpy.max(z), 
                                     zmin = -0.0, 
                                     zstep = 0.1, **cosmo)

    # Convert specified redshifts to cosmic time (age of the universe).
    t = cd.age(z, **cosmo)

    # Integrate to find u(z) = x(z) - w(z), where w is the ionization fraction 
    u = si.odeint(_udot, y0=0.0, t=t,
                  args=(coeff_rec_func, redfunc, ionfunc))
    u = u.flatten()

    w = ionization_from_collapse(z, coeff_ion, temp_min, 
                                 passed_min_mass = passed_min_mass,
                                 **cosmo)
    x = u + w
    x[x > 1.0] = 1.0
    return x, w, t
Esempio n. 3
0
def integrate_ion_recomb(z,
                         ion_func,
                         clump_fact_func,
                         xHe=1.0,
                         temp_gas=1e4, 
                         alpha_B=None,
                         bubble=True,
                         **cosmo):  
    """Integrate IGM ionization and recombination given an ionization function.
    
    Parameters:

    z: array 

       The redshift values at which to calculate the ionized
       fraction. This array should be in reverse numerical order. The
       first redshift specified should be early enough that the
       universe is still completely neutral.

    ion_func: 

       A function giving the ratio of the total density of emitted
       ionizing photons to the density hydrogen atoms (or hydrogen
       plus helium, if you prefer) as a function of redshift.

    temp_gas: 

       Gas temperature used to calculate the recombination coefficient
       if alpha_b is not specified.

    alpha_B:

       Optional recombination coefficient in units of cm^3
       s^-1. In alpha_B=None, it is calculated from temp_gas.

    clump_fact_func: function

      Function returning the clumping factor when given a redshift,
      defined as <n_HII^2>/<n_HII>^2. 

   cosmo: dict

      Dictionary specifying the cosmological parameters.

    Notes:

    We only track recombination of hydrogen, but if xHe > 0, then the
    density is boosted by the addition of xHe * nHe. This is
    eqiuvalent to assuming the the ionized fraction of helium is
    always proportional to the ionized fraction of hydrogen. If
    xHe=1.0, then helium is singly ionized in the same proportion as
    hydrogen. If xHe=2.0, then helium is fully ionized in the same
    proportion as hydrogen.
    
    We assume, as is fairly standard, that the ionized
    fraction is contained in fully ionized bubbles surrounded by a
    fully neutral IGM. The output is therefore the volume filling
    factor of ionized regions, not the ionized fraction of a
    uniformly-ionized IGM.

    I have also made the standard assumption that all ionized photons
    are immediately absorbed, which allows the two differential
    equations (one for ionization-recombination and one for
    emission-photoionizaion) to be combined into a single ODE. 

    """

    # Determine recombination coefficient.
    if alpha_B is None:
        alpha_B_cm = recomb_rate_coeff_HG(temp_gas, 'H', 'B')
    else:
        alpha_B_cm = alpha_B
    alpha_B = alpha_B_cm * cc.Gyr_s / (cc.Mpc_cm**3.)
    print ("Recombination rate alpha_B = %.4g (Mpc^3 Gyr^-1) = %.4g (cm^3 s^-1)" 
           % (alpha_B, alpha_B_cm))

    # Normalize power spectrum.
    if 'deltaSqr' not in cosmo:
        cosmo['deltaSqr'] = cp.norm_power(**cosmo)

    # Calculate useful densities.
    rho_crit, rho_0, n_He_0, n_H_0 = cden.baryon_densities(**cosmo)

    # Boost density to approximately account for helium.
    nn = (n_H_0 + xHe * n_He_0)

    # Function used in the integration.
    # Units: (Mpc^3 Gyr^-1) * Mpc^-3 = Gyr^-1
    coeff_rec_func = lambda z1: (clump_fact_func(z1) * 
                                 alpha_B * 
                                 nn * (1.+z1)**3.)

    # Generate a function that converts age of the universe to z.
    red_func = cd.quick_redshift_age_function(zmax = 1.1 * numpy.max(z), 
                                              zmin = -0.0,
                                              dz = 0.01,
                                              **cosmo)

    ref_func_Gyr = lambda t1: red_func(t1 * cc.Gyr_s)

    # Convert specified redshifts to cosmic time (age of the universe).
    t = cd.age(z, **cosmo)[0]/cc.Gyr_s

    # Integrate to find u(z) = x(z) - w(z), where w is the ionization fraction 
    u = si.odeint(_udot, y0=0.0, t=t,
                  args=(coeff_rec_func, ref_func_Gyr, ion_func, bubble))
    u = u.flatten()

    w = ion_func(z)
    x = u + w
    #x[x > 1.0] = 1.0
    return x, w, t
def integrate_ion_recomb(z,
                         ion_func,
                         clump_fact_func,
                         xHe=1.0,
                         temp_gas=1e4, 
                         alpha_B=None,
                         bubble=True,
                         **cosmo):  
    """Integrate IGM ionization and recombination given an ionization function.
    
    Parameters:

    z: array 

       The redshift values at which to calculate the ionized
       fraction. This array should be in reverse numerical order. The
       first redshift specified should be early enough that the
       universe is still completely neutral.

    ion_func: 

       A function giving the ratio of the total density of emitted
       ionizing photons to the density hydrogen atoms (or hydrogen
       plus helium, if you prefer) as a function of redshift.

    temp_gas: 

       Gas temperature used to calculate the recombination coefficient
       if alpha_b is not specified.

    alpha_B:

       Optional recombination coefficient in units of cm^3
       s^-1. In alpha_B=None, it is calculated from temp_gas.

    clump_fact_func: function

      Function returning the clumping factor when given a redshift,
      defined as <n_HII^2>/<n_HII>^2. 

   cosmo: dict

      Dictionary specifying the cosmological parameters.

    Notes:

    We only track recombination of hydrogen, but if xHe > 0, then the
    density is boosted by the addition of xHe * nHe. This is
    eqiuvalent to assuming the the ionized fraction of helium is
    always proportional to the ionized fraction of hydrogen. If
    xHe=1.0, then helium is singly ionized in the same proportion as
    hydrogen. If xHe=2.0, then helium is fully ionized in the same
    proportion as hydrogen.
    
    We assume, as is fairly standard, that the ionized
    fraction is contained in fully ionized bubbles surrounded by a
    fully neutral IGM. The output is therefore the volume filling
    factor of ionized regions, not the ionized fraction of a
    uniformly-ionized IGM.

    I have also made the standard assumption that all ionized photons
    are immediately absorbed, which allows the two differential
    equations (one for ionization-recombination and one for
    emission-photoionizaion) to be combined into a single ODE. 

    """

    # Determine recombination coefficient.
    if alpha_B is None:
        alpha_B_cm = recomb_rate_coeff_HG(temp_gas, 'H', 'B')
    else:
        alpha_B_cm = alpha_B
    alpha_B = alpha_B_cm * cc.Gyr_s / (cc.Mpc_cm**3.)
    print ("Recombination rate alpha_B = %.4g (Mpc^3 Gyr^-1) = %.4g (cm^3 s^-1)" 
           % (alpha_B, alpha_B_cm))

    # Normalize power spectrum.
    if 'deltaSqr' not in cosmo:
        cosmo['deltaSqr'] = cp.norm_power(**cosmo)

    # Calculate useful densities.
    rho_crit, rho_0, n_He_0, n_H_0 = cden.baryon_densities(**cosmo)

    # Boost density to approximately account for helium.
    nn = (n_H_0 + xHe * n_He_0)

    # Function used in the integration.
    # Units: (Mpc^3 Gyr^-1) * Mpc^-3 = Gyr^-1
    coeff_rec_func = lambda z1: (clump_fact_func(z1) * 
                                 alpha_B * 
                                 nn * (1.+z1)**3.)

    # Generate a function that converts age of the universe to z.
    red_func = cd.quick_redshift_age_function(zmax = 1.1 * numpy.max(z), 
                                              zmin = -0.0,
                                              dz = 0.01,
                                              **cosmo)

    ref_func_Gyr = lambda t1: red_func(t1 * cc.Gyr_s)

    # Convert specified redshifts to cosmic time (age of the universe).
    t = cd.age(z, **cosmo)[0]/cc.Gyr_s

    # Integrate to find u(z) = x(z) - w(z), where w is the ionization fraction 
    u = si.odeint(_udot, y0=0.0, t=t,
                  args=(coeff_rec_func, ref_func_Gyr, ion_func, bubble))
    u = u.flatten()

    w = ion_func(z)
    x = u + w
    #x[x > 1.0] = 1.0
    return x, w, t